首页 > 解决方案 > MongoDB 在 $group $push 中创建数组数组而不是平面数组

问题描述

我试图在 $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"
        }
    ], 
}

我想按 _id 对它们进行分组,然后将 allowedLocations 和 disallowedLocations 数组连接成一个。我的管道中的小组赛阶段如下所示:

{ 
    "$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"
            }
        ]
    } 
}

有没有办法产生一个只有对象作为元素的平面数组?在推送之前我也尝试过使用 $concatArrays ,但这会在数组中创建更多数组。

标签: mongodbmongodb-queryaggregation-framework

解决方案


这里有两个解决方案。您可以在两个数组上运行$unwind以获取单个alloweddisallowed location每个文档,然后运行​​$group阶段:

db.col.aggregate([
    {
        $unwind: "$allowedLocations"
    },
    {
        $unwind: "$disallowedLocations"
    },
    { 
        "$group" : {
            "_id" : "$_id", 
            "allowedLocations" : {
                "$addToSet" : "$allowedLocations"
            }, 
            "disallowedLocations" : {
                "$addToSet" : "$disallowedLocations"
            }
        }
    }
])

或者你可以先运行你的$group然后使用$reduce来展allowedLocations平和disallowedLocations

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" ] }
                }
            }
        }
    }
])

推荐阅读