我有一个看起来像这样的mongoose Schema:
var AnswerSchema = new Schema({
author: {type: Schema.Types.ObjectId, ref: 'User'},
likes: [{type: Schema.Types.ObjectId, ref: 'User'}]
text: String,
....
});
我有一个API端点,可以获取特定用户发布的答案(排除likes
数组)。我想要做的是在likes
数组中特定的user_id是(或不是)时,在mongoose查询返回的答案中添加一个字段(例如“true / false”值)一个答案。这样,如果用户已经喜欢答案,我可以向用户显示请求答案。
我怎样才能以优化的方式实现这一目标?我想避免获取喜欢的数组,然后在我的Javascript代码中查看它以检查是否存在指定的userId,然后在将其发送回客户端之前将其删除...因为听取所有这些听起来是错误的数据从mongoDB到我的节点应用程序什么都没有。我确信使用聚合有一种更好的方法,但我从未使用过它,并且对如何正确使用它感到有些困惑。 数据库可能会变得非常大,因此必须快速优化。
答案 0 :(得分:1)
您可以采用的一种方法是通过聚合框架,它允许您通过 $project
管道添加/修改字段,应用一系列在队列中工作的逻辑运算符来实现期望的最终结果。例如,在上述情况下,这将转换为:
ys
作为在mongo shell中测试的一个例子,让我们在测试集合中插入一些测试文档:
Answer.aggregate()
.project({
"author": 1,
"matched": {
"$eq": [
{
"$size": {
"$ifNull": [
{ "$setIntersection": [ "$likes", [userId] ] },
[]
]
}
},
1
]
}
})
.exec(function (err, docs){
console.log(docs);
})
在测试集合上运行上述聚合管道以获取userId = 2的布尔字段:
db.test.insert([
{
"likes": [1, 2, 3]
},
{
"likes": [3, 2]
},
{
"likes": null
},
{
"another": "foo"
}
])
给出以下输出:
var userId = 2;
db.test.aggregate([
{
"$project": {
"matched": {
"$eq": [
{
"$size": {
"$ifNull": [
{ "$setIntersection": [ "$likes", [userId] ] },
[]
]
}
},
1
]
}
}
}
])