Mongoose:将.project(聚合)与.find()。limit()。sort()等相关联

我有一个mongoose模式看起来像这样:

var AnswerSchema = new Schema({ author: {type: Schema.Types.ObjectId, ref: 'User'}, likes: [{type: Schema.Types.ObjectId, ref: 'User'}], date: {type: Date, default: Date.now}, text: String, .... }); 

截至目前,我通过这样做来查询这个集合:

 Answer.find({ author: profileId, date: {$lt: fromDate} }).sort({date: -1}) .limit(25) .populate('question.sender', 'username username_display name') .exec(function (err, answers) { *code here* }); 

但是,我需要在这个查询中添加一个计算字段,以便知道访问者是否已经喜欢作者的答案(请参阅此问题 ),这要归功于聚合pipe道。 它看起来像这样:

 Answer.aggregate() .project({ "author": 1, "matched": { "$eq": [ { "$size": { "$ifNull": [ { "$setIntersection": [ "$likes", [userId] ] }, [] ] } }, 1 ] } }) .exec(function (err, docs){ console.log(docs); }) 

问题是 :我只需要在由第一个查询过滤的文档上运行此投影。 换句话说,我需要将查找/限制/sorting与项目结合起来。

我怎么能这样做? 我已经尝试在第一个查询(.exec()之前)链接.project(),但它不起作用。 也许我需要通过mongodb的聚合链在第一个查询中做所有的事情?

编辑:这是一个数据集的例子来试试这个:

 { "_id" : ObjectId("56334295e45552c018fc475d"), "author" : ObjectId("561f9c319cdd94401ae160ef"), "likeCount" : 1, "likes" : [ ObjectId("561f9c319cdd94401ae160ef") ], "text" : "This is the answer content", "question" : { "questionId" : ObjectId("56334031e45552c018fc4757"), "sender" : ObjectId("561f9c319cdd94401ae160ef"), "date" : ISODate("2015-10-30T10:02:25.323Z") }, "date" : ISODate("2015-10-30T10:12:37.894Z") }, { "_id" : ObjectId("563246cfa04c1b281b6d97bf"), "author" : ObjectId("561f9c319cdd94401ae160ef"), "likeCount" : 0, "likes" : [], "text" : "Bla bla bla", "question" : { "questionId" : ObjectId("562f9a74a16d6fb418752b37"), "sender" : ObjectId("561f9c319cdd94401ae160ef"), "date" : ISODate("2015-10-27T15:38:28.337Z") }, "date" : ISODate("2015-10-29T16:18:23.020Z") } 

project()方法之前使用聚合stream法API的链接方法match()sort() + limit()

 Answer.aggregate() .match({ "author": profileId, "date": { "$lt": fromDate } }) .sort("-date") .limit(25) .project({ "author": 1, "question.sender": 1, "matched": { "$eq": [ { "$size": { "$ifNull": [ { "$setIntersection": [ "$likes", [userId] ] }, [] ] } }, 1 ] } }) .exec(function (err, docs){ if (err) throw err; console.log(docs); var answers = docs.map(function(doc) { return new Answer(doc); }); Answer.populate(answers, { "path": "question.sender", "select": "username username_display name" }, function(err, results) { if (err) throw err; console.log(JSON.stringify(results, undefined, 4 )); res.json(results); }); });