Mongoose / MongoDB:$ in和.sort()
我每天打一个跟随50个成员数据的API,并使用mongoose把JSON转换成集合中的单个文档。 在几天之间有数据是一致的,例如每个成员的标签(游戏中成员的id),但是有不同的数据(不同的分数等)。 每个文档都有一个createdAt
属性。
我想为每个成员find最近的文档,从而有一个数组与每个成员的标记。
我正在使用下面的查询来查找标签匹配的所有文档,但是他们正在返回所有文档,而不仅仅是一个。 如何将文档sorting/限制到最新的文档,同时保留一个查询(或者是否有更多的“mongodb方式”)?
memberTags = [1,2,3,4,5]; ClanMember.find({ 'tag': { $in: memberTags } }).lean().exec(function(err, members) { res.json(members); });
谢谢
您可以通过聚合框架进行查询。 您的查询将涉及一个pipe道 ,它具有处理input文档的阶段,以提供所需的结果。 在你的情况下,pipe道将有一个$match
阶段,作为初始filter的查询。 $match
使用标准的MongoDB查询,因此您仍然可以使用$in
查询。
下一步将是通过createdAt
字段对这些过滤的文档进行sorting。 这是使用$sort
运算符完成的。
前面的stream水线阶段涉及汇总订购的文档以返回每个组的最前面的文档。 $group
运算符和$first
累加器是使这成为可能的运算符。
完全放在这里,你可以运行下面的集合操作来获得你想要的结果:
memberTags = [1,2,3,4,5]; ClanMember.aggregate([ { "$match": { "tag": { "$in": memberTags } } }, { "$sort": { "tag": 1, "createdAt: -1 " } }, { "$group": { "_id": "$tag", "createdAt": { "$first": "$createdAt" } /*, include other necessary fields as appropriate using the $first operator eg "otherField1": { "$first": "$otherField1" }, "otherField2": { "$first": "$otherField2" }, ... */ } } ]).exec(function(err, members) { res.json(members); });
或者使用find()
来调整当前查询,以便您可以对两个字段进行sorting,即tag
(升序)和createdAt
(降序)属性。 然后,您可以使用限制select前5个文档,如下所示:
memberTags = [1,2,3,4,5]; ClanMember.find( { 'tag': { $in: memberTags } }, // query {}, // projection { // options sort: { 'createdAt': -1, 'tag': 1 }, limit: memberTags.length, skip: 0 } ).lean().exec(function(err, members) { res.json(members); });
要么
memberTags = [1,2,3,4,5]; ClanMember.find({ 'tag': { $in: memberTags } }).sort('-createdAt tag') .limit(memberTags.length) .lean() .exec(function(err, members) { res.json(members); });
那么,首先让我们使用findOne()
以便只从请求中获得一个文档。然后按照最新的文档sorting,可以使用.sort({elementYouWantToSort: -1})
(-1表示要sorting从最新到最旧,以及从最旧到最新)我build议在_id上使用这个函数,它已经包含了文档的创builddate,它给了我们下面的请求:
ClanMember.findOne({ 'tag': { $in: memberTags } }).sort({_id: -1}).lean().exec(function(err, members) { res.json(members); });