Mongodb在数组字段上查找匹配查询不起作用

时间:2017-05-08 16:09:15

标签: mongodb mongodb-query aggregation-framework

我有以下架构与colletcion&我的mongodb有与之相关的价值观。以下是此示例文档。

{
    "_id" : ObjectId("590d46d685a155f33a4a1f1d"),
    "domainName" : "gmail.com",
    "userlevels" : [ 
        {
            "labId" : 104,
            "userlevel" : true
        }, 
        {
            "labId" : 401,
            "userlevel" : false
        }, 
        {
            "labId" : 202,
            "userlevel" : true
        }, 
        {
            "labId" : 102,
            "userlevel" : true
        }, 
        {
            "labId" : 108,
            "userlevel" : true
        }, 
        {
            "labId" : 110,
            "userlevel" : true
        }, 
        {
            "labId" : 120,
            "userlevel" : true
        }, 
        {
            "labId" : 820,
            "userlevel" : false
        }
    ],
    "labconfigs" : [ 
        ObjectId("590d46d685a155f33a4a1f0c"), 
        ObjectId("590d46d685a155f33a4a1f11"), 
        ObjectId("590d46d685a155f33a4a1f10"), 
        ObjectId("590d46d685a155f33a4a1f0d"), 
        ObjectId("590d46d685a155f33a4a1f12"), 
        ObjectId("590d46d685a155f33a4a1f0f"), 
        ObjectId("590d46d685a155f33a4a1f0e"), 
        ObjectId("591087b0b18c5f472905343a")
    ]
}

所以我们想要的是所有在labID的特定范围内匹配的文档,只有在数组中匹配的字段(“userlevels”)才能在结果输出中。

假设我们希望收集中的所有匹配文档的范围介于$ gt到200之间,则应该跟随所需的输出。

{
    "_id" : ObjectId("590d46d685a155f33a4a1f1d"),
    "domainName" : "gmail.com",
    "userlevels" : [ 
        {
            "labId" : 104,
            "userlevel" : true
        },
        {
            "labId" : 102,
            "userlevel" : true
        }, 
        {
            "labId" : 108,
            "userlevel" : true
        }, 
        {
            "labId" : 110,
            "userlevel" : true
        }, 
        {
            "labId" : 120,
            "userlevel" : true
        }
    ]
}

我尝试过的&这是我的mongodb查询。

            db.collection('domains').find({
                                           "userlevels":{ $all :[
                                               { "$elemMatch" : { "labId" :{$gte : 100, $lt:200 }}}
                                               ]}
                                          }).toArray(function(err, items) {
              console.log("items",items);
                                 });

它回复了与lab_id(100到200)范围内的文档匹配的所有文档,但它在用户级别回复了lab_id。

3 个答案:

答案 0 :(得分:1)

您必须使用聚合管道。

初始$match,以限制至少有一个userlevels数组元素符合labId条件的文档,后跟$filter cond来限制元素在数组中匹配每个匹配文档中的labId条件。

$project包含(1)domainName并用过滤后的值覆盖userlevels

aggregate({
    $match: {
        "userlevels.labId": {
            $gt: 100,
            $lt: 200
        }
    }
}, {
    $project: {
        domainName: 1,
        userlevels: {
            $filter: {
                input: "$userlevels",
                as: "result",
                cond: {
                    $and: [{
                        $gt: ["$$result.labId", 100]
                    }, {
                        $lt: ["$$result.labId", 200]
                    }]
                }
            }
        }
    }
})

答案 1 :(得分:0)

你走了:

db.domains.aggregate([
    { $unwind : '$userlevels'},
    { $match : { 'userlevels.labId' : { $gt: 100, $lt: 200 } }},
    { $group : {
        '_id' : '$_id',
        'domainName': { '$first' : '$domainName'},
        "userlevels": { "$push": "$userlevels" }
    }}
]);

答案 2 :(得分:0)

对于Mongodb 3.0版&下面使用这个对我有用的查询。

    db.collection('domains').aggregate({
            $match: {
                "userlevels.labId": {
                    $gt: 100,
                    $lt: 200
                }
            }
        }, {
            $project: {
                domainName: 1,
                userlevels: {
                    "$setDifference": [{
                        $map: {
                        input: "$userlevels",
                        as: "result",
                        in: {
                            $cond: [{
                                $and: [{
                                    $gt: ["$$result.labId", 100]
                                }, {
                                    $lt: ["$$result.labId", 200]
                                }, {
                                    $eq: ["$$result.userlevel", true]
                                }]
                            },
                                "$$result",
                                false
                            ]
                        }
                    }},
                   [false]
                  ]
                }
            }
        }

     })