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

标签 mongodb mongodb-query aggregation-framework

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

这是我的数据集。

我的文档:

{
    "_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
}

我不希望第一个公共(public)字段为空。有人可以让我知道我做错了什么吗?或者我可以采取的任何解决方法。

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

我的目标是用用户定义列表中的公共(public)元素替换标签数组,或者添加带有公共(public)元素的新字段。我正在尝试在我的示例中稍后进行。

最佳答案

公共(public)字段为空的原因是因为您的“pendingEntries”数组和用户定义的数组没有共同的元素。您真正想要的是返回一个数组,其中包含“标签”数组和用户定义数组中出现的元素。为此,您只需使用 $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" : [ ]
        }
    ]
}

关于mongodb - 返回子文档数组与用户定义数组的交集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36630862/

相关文章:

java - Mongo 模板在 Spring.Mongodb 中按日期间隔聚合

javascript - 我如何将 dd-mm-yyyy 之类的日期转换为 ISO 日期格式,以存储在 mongoDB 中

mongodb - 如何在 mongoskin 中设置安全变量?

javascript - Nodejs : . then() 语句在 Promise.all() 之后不执行

mongodb - 包含 mongodb 聚合中的字段

node.js - MongoDB - 过滤条件和 3-deep 对象

java - 如何使用 Android AsyncHttpClient 从 MongoDB 获取数据

php - 如何在 phalcon 中将 "group by"、 "having"查询从 mysql 转换为 mongodb

Mongodb 分组数据 - mapReduce 还是聚合?

mongodb - 在 mongodb 中的字符串数组中查找并替换