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

use*_*148 4 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" ] }
Run Code Online (Sandbox Code Playgroud)

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

{"_id":"theID", "result":["1", "2", "3", "4", "5"]}
Run Code Online (Sandbox Code Playgroud)

ID并不重要。注意一个array1array2,或者两者都不可以存在于一个文件,他们甚至可以是空的。我尝试了许多聚合和级联查询命令,但无法提供所需的响应。

sty*_*ane 5

为此,您将需要使用.aggregate()提供对聚合管道的访问的方法。

流水线的第一阶段使用$match运算符过滤掉那些同时存在array1array2不存在的文档,并使用$exists运算符和点符号。该操作员减少了管道下方要处理的文档数量。

下一阶段是$project您基本上使用$setUnion 返回包含包含在任何数组中的元素的数组的步骤;它还会过滤掉结果中的重复元素。也不要使用$ifNull运算符,该运算符根据第一个表达式的计算结果是否为空(此处的表达式为“ array1”和“ array2”)返回第一个表达式或空数组的值。从那里,您需要使用$unwind运算符对“数组”字段进行反规范化。

在管道的最后阶段,您将$group使用$addToSet累加器运算符,该运算符将返回唯一值数组。

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" } 
    }} 
] )
Run Code Online (Sandbox Code Playgroud)

产生:

{ "_id" : null, "arrays" : [ "5", "3", "1", "4", "2" ] }
Run Code Online (Sandbox Code Playgroud)