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); });