mongodb聚合匹配多个$并在同一个字段上

时间:2015-05-04 16:12:43

标签: mongodb aggregation-framework

我有这样的文件:

{
    "ExtraFields" : [
    {
        "value" : "print",
        "fieldID" : ObjectId("5535627631efa0843554b0ea")
    },
    {
        "value" : "14",
        "fieldID" : ObjectId("5535627631efa0843554b0eb")
    },
    {
        "value" : "POLYE",
        "fieldID" : ObjectId("5535627631efa0843554b0ec")
    },
    {
        "value" : "30",
        "fieldID" : ObjectId("5535627631efa0843554b0ed")
    },
    {
        "value" : "0",
        "fieldID" : ObjectId("5535627631efa0843554b0ee")
    },
    {
        "value" : "0",
        "fieldID" : ObjectId("5535627731efa0843554b0ef")
    },
    {
        "value" : "0",
        "fieldID" : ObjectId("5535627831efa0843554b0f0")
    },
    {
        "value" : "42",
        "fieldID" : ObjectId("5535627831efa0843554b0f1")
    },
    {
        "value" : "30",
        "fieldID" : ObjectId("5535627831efa0843554b0f2")
    },
    {
        "value" : "14",
        "fieldID" : ObjectId("5535627831efa0843554b0f3")
    },
    {
        "value" : "19",
        "fieldID" : ObjectId("5535627831efa0843554b0f4")
    }
],
        "id" : ObjectId("55369e60733e4914550832d0"), "title" : "A product"
}

我想要的是匹配ExtraFields数组中的一个或多个集合。例如,包含值print和30的所有产品。由于可以在多个fieldID中找到一个值(如0或true),我们需要创建一个类似

的集合
WHERE (fieldID : ObjectId("5535627631efa0843554b0ea"), value : "print")

我遇到问题的地方是查询多个字段。我提出的管道是:

db.products.aggregate([
    {'$unwind': '$ExtraFields'},

{
    '$match': {
        '$and': [{
            '$and': [{'ExtraFields.value': {'$in': ["A52A2A"]}}, {
                'ExtraFields.fieldID': ObjectId("5535627631efa0843554b0ea")
            }]
        }

            ,
            {
                '$and': [{'ExtraFields.value': '14'}, {'ExtraFields.fieldID': ObjectId("5535627631efa0843554b0eb")}]
            }

        ]
    }
},


]);

这会返回零结果,但这是我想要理论上做的。匹配包含第1组和包含第2组的所有项目。

最终结果应该看起来像分面搜索输出:

[ 
    {
        "_id" : {
            "values" : "18",
            "fieldID" : ObjectId("5535627831efa0843554b0f3")
        },
        "count" : 2
    }, 
    {
        "_id" : {
            "values" : "33",
            "fieldID" : ObjectId("5535627831efa0843554b0f2")
        },
        "count" : 1
    }
]

有什么想法吗?

1 个答案:

答案 0 :(得分:5)

您可以尝试以下聚合管道

db.products.aggregate([
    {
        "$match": {
            "ExtraFields.value": { "$in": ["A52A2A", "14"] },
            "ExtraFields.fieldID": { 
                "$in": [
                    ObjectId("5535627631efa0843554b0ea"),
                    ObjectId("5535627631efa0843554b0eb")
                ] 
            }
        }
    },
    {
        "$unwind": "$ExtraFields"
    },
    {
        "$match": {
            "ExtraFields.value": { "$in": ["A52A2A", "14"] },
            "ExtraFields.fieldID": { 
                "$in": [
                    ObjectId("5535627631efa0843554b0ea"),
                    ObjectId("5535627631efa0843554b0eb")
                ] 
            }
        }
    },
    {
        "$group": {
            "_id": {
                "value": "$ExtraFields.value",
                "fieldID": "$ExtraFields.fieldID"
            },
            "count": {
                "$sum": 1
            }
        }
    }
])

提供样本文件后,会给出输出:

/* 1 */
{
    "result" : [ 
        {
            "_id" : {
                "value" : "14",
                "fieldID" : ObjectId("5535627631efa0843554b0eb")
            },
            "count" : 1
        }
    ],
    "ok" : 1
}