条件投影,如果元素存在于mongodb

时间:2015-11-14 00:03:12

标签: node.js mongodb nosql

如果值与巨大的子数组中的值匹配,是否有直接的方法来投影新字段。我知道我可以在$ match条件中使用$ elemMatch或$,但这不允许我获得其余的非匹配值(在我的情况下是用户)。

基本上我想列出所有类型1项目并在突出显示订阅用户时显示所有用户。我想通过mongodb这样做的原因是为了避免为每个项目迭代超过数千个用户。事实上,这是我的问题的第2部分,我可以限制将返回的用户数组的数量,我只需要返回大约10个数组值而不是数千个。

集合结构是

   {
     name: "Coke",
     type: 2,
     users:[{user: 13, type:1},{ user:2: type:2}]
    },
    {
     name: "Adidas",
     type: 1,
     users:[{user:31, type:3},{user: 51, type:1}]
     },
    {
     name: "Nike",
     type: 1,
     users:[{user:21, type:3},{user: 31, type:1}]
     }

总文件数量为200,000 +并且还在增长...... 每个文档都有10,000~5,000个用户..

预期回报

    {
     isUser: true,
     name: "Adidas",
     type: 1,
     users:[{user:31, type:3},{user: 51, type:1}]
     },
    {
     isUser: false,
     name: "Nike",
     type: 1,
     users:[{user:21, type:3},{user: 31, type:1}]
     }

我一直在尝试这个

.aggregate([
            {$match:{type:1}},
            {$project:
                     {
                      isUser:{$elemMatch:["users.user",51]},
                      users: 1,
                      type:1,
                      name: 1
                     }
             }
           ])

这失败了,我收到错误"超出最大堆栈大小"。我已经尝试了很多组合,似乎没有工作。我真的想避免多次调用mongodb。这可以在一次通话中完成吗?

我被告知要放松,但我有点担心这会导致记忆问题。

如果我使用的是mysql,一个简单的子查询就可以完成这项任务......我希望我能在mongodb中忽略一个类似的简单解决方案。

1 个答案:

答案 0 :(得分:0)

处理数组元素的条件并使用 $anyElementTrue 的组合来匹配结果, $ifNull 将数组计算为集合,如果任何元素为真,则返回true否则, $map 运算符将充当安全网,评估以下 $map 表达式并返回表达式的值,如果表达式计算为非空值。 $ifNull 运算符中的 $anyElementTrue 旨在将条件语句表达式应用于users数组中的每个项目,并返回应用了数组的数组结果。然后将使用 enter image description here 评估生成的数组,这将最终计算并返回每个文档的isUser字段:

db.collection.aggregate([
    { "$match": { "type": 1} },
    {
        "$project": {
            "name": 1, "type": 1,
            "isUser": {
                "$anyElementTrue": [
                    {
                        '$ifNull': [ 
                            {
                                "$map": {
                                    "input": "$users",
                                    "as": "el",
                                    "in": { "$eq": [ "$$el.user",51] }
                                }
                            },
                            [false]
                        ]
                    }
                ]
            }
        }
    }
])