如何将许多文档中的两个字段数组合并为一个集合?

时间:2015-08-07 20:19:31

标签: mongodb aggregation-framework

我有MongoDB集合数据,如下所示:

{ "_id" : "1", "array1" : [ "1", "2" ] },
{ "_id" : "2", "array2" : [ "1", "3" ] },
{ "_id" : "3", "array1" : [ ] },
{ "_id" : "4", "array2" : [ ] },
{ "_id" : "5" },
{ "_id" : "6", "array1" : [ "3", "4" ], "array2" : [ "5" ] }

我想找到一个只返回单个数组中的唯一数组值的查询,如下所示:

{"_id":"theID", "result":["1", "2", "3", "4", "5"]}

ID并不重要。请注意,array1array2,两者或两者都不能出现在文档中,甚至可以为空。我已经尝试了很多聚合和级联查询命令,但却无法得到所需的响应。

1 个答案:

答案 0 :(得分:4)

要执行此操作,您需要使用.aggregate()方法来提供对聚合管道的访问。

管道中的第一个阶段使用$match运算符,使用$exists运算符和{{过滤掉array1array2都不存在的文档3}}。此运算符减少了管道中向下处理的文档数。

下一阶段是dot notation,你基本上使用$project返回一个数组,其中包含任何数组中出现的元素;它还会过滤掉结果中的重复元素。也不是使用$setUnion运算符返回第一个表达式或空数组的值,具体取决于第一个表达式是否计算为null(此处表达式为" array1"和" array2& #34)。 从那里,你需要对"阵列进行去标准化。使用$ifNull运算符的字段。

在管道的最后一个阶段,你$unwind并使用$group累加器运算符返回一个唯一值数组。

db.getCollection('collection').aggregate([
    { "$match": { 
        "$or": [ 
            { "array1.0": { "$exists": true } }, 
            { "array2.0": { "$exists": true } }
        ]
    }}, 
    { "$project": { 
        "arrays": { 
            "$setUnion": [ 
                { "$ifNull": [ "$array1", [] ] },
                { "$ifNull": [ "$array2", [] ] } 
            ] 
        }
    }}, 
    { "$unwind": "$arrays" }, 
    { "$group": { 
        "_id": null, 
        "arrays": { "$addToSet": "$arrays" } 
    }} 
] )

哪个收益率:

{ "_id" : null, "arrays" : [ "5", "3", "1", "4", "2" ] }