MongoDB在$group$push中创建数组,而不是平面数组

MongoDB在$group$push中创建数组,而不是平面数组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我正在尝试在$unwind操作后对一组文档进行分组。我的文档如下所示: { "_id" : ObjectId("5cdb5b5acadf5100019da2f4"), "allowedLocations" : [ { "type" : "country", "value" : "world", "label" : "World" } ], "disal

我正在尝试在$unwind操作后对一组文档进行分组。我的文档如下所示:

{ 
    "_id" : ObjectId("5cdb5b5acadf5100019da2f4"), 
    "allowedLocations" : [
        {
            "type" : "country", 
            "value" : "world", 
            "label" : "World"
        }
    ], 
    "disallowedLocations" : [
        {
            "type" : "country", 
            "value" : "CF", 
            "label" : "Central African Republic"
        }, 
        {
            "type" : "country", 
            "value" : "CN", 
            "label" : "China"
        }
    ], 
}

{ 
    "_id" : ObjectId("5cdb5b5acadf5100019da2f4"), 
    "allowedLocations" : [
        {
            "type" : "country", 
            "value" : "US", 
            "label" : "United States of America"
        }
    ], 
    "disallowedLocations" : [
        {
            "type" : "country", 
            "value" : "CA", 
            "label" : "Canada"
        }, 
        {
            "type" : "country", 
            "value" : "MX", 
            "label" : "Mexico"
        }
    ], 
}
{ 
    "$group" : {
        "_id" : "$_id", 
        "allowedLocations" : {
            "$push" : "$allowedLocations"
        }, 
        "disallowedLocations" : {
            "$push" : "disallowedLocations"
        }
    }
}
我想按_id对它们进行分组,然后将allowedLocations和disallowedLocations数组连接成一个数组。我管道中的小组阶段如下所示:

{ 
    "_id" : ObjectId("5cdb5b5acadf5100019da2f4"), 
    "allowedLocations" : [
        {
            "type" : "country", 
            "value" : "world", 
            "label" : "World"
        }
    ], 
    "disallowedLocations" : [
        {
            "type" : "country", 
            "value" : "CF", 
            "label" : "Central African Republic"
        }, 
        {
            "type" : "country", 
            "value" : "CN", 
            "label" : "China"
        }
    ], 
}

{ 
    "_id" : ObjectId("5cdb5b5acadf5100019da2f4"), 
    "allowedLocations" : [
        {
            "type" : "country", 
            "value" : "US", 
            "label" : "United States of America"
        }
    ], 
    "disallowedLocations" : [
        {
            "type" : "country", 
            "value" : "CA", 
            "label" : "Canada"
        }, 
        {
            "type" : "country", 
            "value" : "MX", 
            "label" : "Mexico"
        }
    ], 
}
{ 
    "$group" : {
        "_id" : "$_id", 
        "allowedLocations" : {
            "$push" : "$allowedLocations"
        }, 
        "disallowedLocations" : {
            "$push" : "disallowedLocations"
        }
    }
}
问题是,我得到的结果不是一个两个数组都连接在一起的文档,而是一个数组数组,数组的每个元素都是每个文档的数组:

{ 
    "_id" : ObjectId("5cdb5b5acadf5100019da2f4"), 
    "allowedLocations" : [
        [
            {
                "type" : "country", 
                "value" : "US", 
                "label" : "United States of America"
            }
        ],
        [
            {
                "type" : "country", 
                "value" : "world", 
                "label" : "World"
            }
        ],
    ], 
    "disallowedLocations" : [
        [
            {
                "type" : "country", 
                "value" : "CF", 
                "label" : "Central African Republic"
            }, 
            {
                "type" : "country", 
                "value" : "CN", 
                "label" : "China"
            }
        ],
        [
            {
                "type" : "country", 
                "value" : "CA", 
                "label" : "Canada"
            }, 
            {
                "type" : "country", 
                "value" : "MX", 
                "label" : "Mexico"
            }
        ]
    } 
}

是否有一种方法可以生成仅以对象作为元素的平面阵列?在推送之前,我还尝试了$concatarray,但这会在阵列中创建更多的阵列。

这里有两个解决方案。您可以在这两个阵列上运行,以获得每个文档的单个
允许的
不允许的
位置
,然后运行阶段:

或者,您可以先运行,然后使用展开
允许的位置
不允许的位置

db.col.aggregate([
    { 
        "$group" : {
            "_id" : "$_id", 
            "allowedLocations" : {
                "$push" : "$allowedLocations"
            }, 
            "disallowedLocations" : {
                "$push" : "$disallowedLocations"
            }
        }
    },
    {
        $project: {
            _id: 1,
            allowedLocations: {
                $reduce: {
                    input: "$allowedLocations",
                    initialValue: [],
                    in: { $concatArrays: [ "$$value", "$$this" ] }
                }
            },
            disallowedLocations: {
                $reduce: {
                    input: "$disallowedLocations",
                    initialValue: [],
                    in: { $concatArrays: [ "$$value", "$$this" ] }
                }
            }
        }
    }
])

为什么不在执行
$group
之前先
$unwind
不允许的位置
允许的位置
?第一个解决方案应该是
$addToSet
而不是
$push
,以避免数组中出现重复的条目。@VikashSingh这是真的,谢谢。尽管如此,我还是喜欢第二个;)