返回子文档数组与用户定义数组的交集?

时间:2016-04-14 18:13:33

标签: mongodb mongodb-query aggregation-framework

我正在尝试使用Mongo Aggregation Framework来查找文档中的数组与另一个用户定义的数组之间的交集。 我没有得到正确的结果,我的猜测是因为我在数组中有数组。

这是我的数据集。

我的文件:

{
    "_id" : 1,
    "pendingEntries" : [ 
        {
            "entryID" : ObjectId("5701b4c3c6b126083332e65f"),
            "tags" : [ 
                {
                    "tagKey" : "owner",
                    "tagValue" : "john"
                }, 
                {
                    "tagKey" : "ErrorCode",
                    "tagValue" : "7001"
                }, 
                {
                    "tagKey" : "ErrorDescription",
                    "tagValue" : "error123"
                }
            ],
            "entryTime" : ISODate("2016-04-04T00:26:43.167Z")
        }
    ]
},

/* 1 */
{
    "_id" : 2,
    "pendingEntries" : [ 
        {
            "entryID" : ObjectId("5701b4c3c6b126083332e65d"),
            "tags" : [ 
                {
                    "tagKey" : "owner",
                    "tagValue" : "peter"
                }, 
                {
                    "tagKey" : "ErrorCode",
                    "tagValue" : "6001"
                }, 
                {
                    "tagKey" : "JIRA",
                    "tagValue" : "Oabc-123"
                }
            ],
            "entryTime" : ISODate("2016-04-04T00:26:43.167Z")
        }
    ]
},

/* 2 */
{
    "_id" : 3,
    "pendingEntries" : [ 
        {
            "entryID" : ObjectId("5701b4c3c6b126083332e65c"),
            "tags" : [ 
                {
                    "tagKey" : "owner",
                    "tagValue" : "abc"
                }, 
                {
                    "tagKey" : "ErrorCode",
                    "tagValue" : "6001"
                }, 
                {
                    "tagKey" : "JIRA",
                    "tagValue" : "abc-123"
                }
            ],
            "entryTime" : ISODate("2016-04-04T00:26:43.167Z")
        }
    ]
}

我的查询:

db.entrylike.aggregate(
   [
     { $project: { "pendingEntries.entryID": 1, "common": { $setIntersection: [ "$pendingEntries.tags", [{ "tagKey" : "ErrorCode", "tagValue" : "7001" }] ] } } }
   ]
)

结果:

{
    "result" : [ 
        {
            "_id" : 1,
            "pendingEntries" : [ 
                {
                    "entryID" : ObjectId("5701b4c3c6b126083332e65f")
                }
            ],
            "common" : []
        }, 
        {
            "_id" : 2,
            "pendingEntries" : [ 
                {
                    "entryID" : ObjectId("5701b4c3c6b126083332e65d")
                }
            ],
            "common" : []
        }, 
        {
            "_id" : 3,
            "pendingEntries" : [ 
                {
                    "entryID" : ObjectId("5701b4c3c6b126083332e65c")
                }
            ],
            "common" : []
        }
    ],
    "ok" : 1
}

我不期望第一个共同领域是空的。有人能让我知道我做错了什么吗?或者我可以采取的任何工作。

我正在使用mongodb 3.0.8。我知道Mongodb 3.2可以提供一些功能来满足我的需求,但3.2升级不在我们的管道中,我希望尽可能使用Mongo3.0来解决这个问题。

我的目标是将tag数组替换为用户定义列表中的公共元素,或添加具有公共元素的新字段。我试图在后面的例子中使用。

1 个答案:

答案 0 :(得分:2)

公共字段为空的原因是因为“pendingEntries”数组和用户定义的数组没有共同的元素。你真正想要的是返回一个数组,其中包含出现在“tags”数组中的元素和用户定义的数组。为此,您只需使用$map运算符并将$setIntersection运算符应用于“pendingEntries”数组中的每个子文档“tags”。

db.entrylike.aggregate([
    { "$project": { 
        "common": { 
            "$map": { 
                "input": "$pendingEntries", 
                "as": "p",
                "in": { 
                    "entryID": "$$p.entryID",
                    "tags": { 
                        "$setIntersection": [ 
                            "$$p.tags", 
                            { "$literal": [
                                { 
                                    "tagKey" : "ErrorCode", 
                                    "tagValue" : "7001" 
                                }
                            ]}
                        ]
                    }
                }
            }
        }
    }}
])

返回:

{
    "_id" : 1,
    "common" : [
        {
            "entryID" : ObjectId("5701b4c3c6b126083332e65f"),
            "tags" : [
                {
                    "tagKey" : "ErrorCode",
                    "tagValue" : "7001"
                }
            ]
        }
    ]
}
{
    "_id" : 2,
    "common" : [
        {
            "entryID" : ObjectId("5701b4c3c6b126083332e65d"),
            "tags" : [ ]
        }
    ]
}
{
    "_id" : 3,
    "common" : [
        {
            "entryID" : ObjectId("5701b4c3c6b126083332e65c"),
            "tags" : [ ]
        }
    ]
}