当指定的值在数组中时,向返回的对象添加字段(布尔值),而不包括数组本身

时间:2015-11-20 16:06:57

标签: mongodb mongoose

我有一个看起来像这样的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到我的节点应用程序什么都没有。我确信使用聚合有一种更好的方法,但我从未使用过它,并且对如何正确使用它感到有些困惑。 数据库可能会变得非常大,因此必须快速优化。

1 个答案:

答案 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
                ]
            }
        }
    }
])