所有数组字段的MongoDB条件

时间:2014-08-11 09:09:48

标签: mongodb mongodb-query aggregation-framework

它可能在mongodb中查找查找文档,其中字段是一个数组,其所有元素都满足条件?

例如:

{
    "_id" : ObjectId("53d63d0f5c7ff000227cd372"),
     "works" : [ 
            {
                "code" : "A001",
                "items" : [ 
                    {
                        "_id" : "534664b081362062015d1b77",
                        "qty" : 6
                    }, 
                    {
                        "_id" : "534ba71f394835a7e51dd938",
                        "qty" : 5
                    }
                ],
                "name" : "Cambiar bombilla",
                "price" : 100,
                "Date" : "2014-07-30T09:43:17.593Z",
                "TechnicianId" : "538efd918163b19307c59e8e",
                "percent" : 2,
                "_id" : ObjectId("53d63d0f5c7ff002207cd372")
            }, 
            {
                "code" : "A001",
                "name" : "Cambiar bombilla",
                "price" : 100,
                "type" : "Bombillas",
                "TechnicianId" : "538efd918163b19307c59e8e",
                "date" : "2014-07-31T13:36:34.019Z",
                "orderId" : "53d63d0f5c7ff000007cd372",
                "_id" : ObjectId("53da466568c26f8a72b50fcb"),
                "percent" : 66
            }
        ]
},
{
    "_id" : ObjectId("53d63d0f5c7ff000007cd372"),
     "works" : [ 
            {
                "code" : "A001",
                "items" : [ 
                    {
                        "_id" : "534664b081362062015d1b77",
                        "qty" : 6
                    }, 
                    {
                        "_id" : "534ba71f394835a7e51dd938",
                        "qty" : 5
                    }
                ],
                "name" : "Cambiar bombilla",
                "price" : 100,
                "Date" : "2014-07-30T09:43:17.593Z",
                "TechnicianId" : "538efd918163b19307c59e8e",
                "percent" : 2,
                "_id" : ObjectId("53d63d0f5c7ff002207cd372")
            }, 
            {
                "code" : "A001",
                "name" : "Cambiar bombilla",
                "price" : 100,
                "type" : "Bombillas",
                "TechnicianId" : "538efd918163b19307c59e8e",
                "date" : "2014-07-31T13:36:34.019Z",
                "orderId" : "53d63d0f5c7ff000007cd372",
                "_id" : ObjectId("53da466568c26f8a72b50fcb"),
            }
        ]
}

我需要找到像第一个文档这样的文档,因为在工作字段中他的子文档有百分比,但在第二个文档中,第二个位置的工作数组没有百分比。 我希望我能解释一下。

1 个答案:

答案 0 :(得分:1)

以简单的方式测试数组的每个元素中是否存在字段并不容易。可以测试值以购买密钥需要更多的工作。

使用聚合框架完成该方法,以便处理数组元素的条件,然后匹配结果。

首先使用MongoDB 2.6及更高版本,您可以获得一些帮助:

db.collection.aggregate([
    // Filter out to match only possible documents
    { "$match": {
        "works.percent": { "$exists": true }
    }},

    // Find matching through projection
    { "$project": {
        "works": 1,
        "matched": {
            "$allElementsTrue": {
                "$map": {
                    "input": "$works",
                    "as": "el",
                    "in": { "$ifNull": [ "$$el.percent", false ] }
                }
            }
        }
    }},

    // Filter to return only the true matches
    { "$match": { "matched": true } }

])

或者在先前版本中使用$unwind可能会更长,可能更慢:

db.collection.aggregate([
    // Filter out to match only possible documents
    { "$match": {
        "works.percent": { "$exists": true }
    }},

    // Unwind the array
    { "$unwind": "$works" },

    // Find matching by conditionally evaluating and grouping
    { "$group": {
        "_id": "$_id",
        "works": { "$push": "$works" },
        "matched": { 
            "$min": {
                "$cond": [
                    { "$ifNull": [ "$works.percent", false ] },
                    true,
                    false
                ]
            }
        }
    }}

    // Filter to return only the true matches
    { "$match": { "matched": true } }

])

在任何一种情况下,$ifNull运算符都是聚合运算符意义上的$exists运算符的等效运算符。 "查询" $exists的表单测试字段是否存在,$ifNull计算字段存在的位置然后返回值,否则返回备用参数。

但是基本上需要处理数组以查看是否所有元素都存在必需的字段,因为没有相应的标准查询。