我有一个像这样的mongoose Schema:
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*
});
但是我需要在此查询中添加一个计算字段,以了解访问者是否已经喜欢作者的答案(请参阅this question),这要归功于聚合管道。它看起来像这样:
Answer.aggregate()
.project({
"author": 1,
"matched": {
"$eq": [
{
"$size": {
"$ifNull": [
{ "$setIntersection": [ "$likes", [userId] ] },
[]
]
}
},
1
]
}
})
.exec(function (err, docs){
console.log(docs);
})
问题:我需要在仅由第一个查询过滤的文档上运行此投影。换句话说,我需要将find / limit / sort与项目结合起来。
我怎么能这样做?我尝试在第一个查询之后(在.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")
}
答案 0 :(得分:2)
使用汇总的流畅API链接方法 match()
, sort()
+ limit()
在 project()
方法之前:
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);
});
});