【问题标题】:MongoDB creates array of arrays in $group $push instead of flat arrayMongoDB 在 $group $push 中创建数组数组而不是平面数组
【发布时间】:2019-10-19 11:12:56
【问题描述】:

我试图在 $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 ,但这会在数组中创建更多数组。

【问题讨论】:

  • 在执行$group 之前为什么不直接$unwind disallowedLocationsallowedLocations

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

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

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

或者您可以先运行$group,然后使用$reduceallowedLocationsdisallowedLocations 展平:

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

【讨论】:

  • 第一个解决方案应该有 $addToSet 而不是 $push 以避免数组中的重复条目。
  • @VikashSingh 这是真的,谢谢。尽管如此,我更喜欢第二个;)
猜你喜欢
  • 1970-01-01
  • 2021-12-17
  • 2013-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多