首页 > 解决方案 > MongoDB 按 id 对文档进行分组并从文档中合并匹配的数组元素

问题描述

我正在尝试使用 Mongo 聚合框架按 id 对文档进行分组,然后将每个文档中的“事件”数组合并到一个数组中。我尝试过不同的组累加器;push、first、last 等。使用 push 会生成一个数组数组。但我想要一个包含所有事件对象的数组。MongoDB 4.4

文件

{
        _id: 123,
        name: "John",
        events: [
            {
                start: "2020-01-01",
                end: "2020-01-01"
            },
            {
                start: "2020-01-01",
                end: "2020-01-01"
            }
        ]
    },
    {
        _id: 123,
        name: "John",
        events: [
            {
                start: "2020-01-21",
                end: "2020-01-21"
            },
        ]
    },
        {
            _id: 456,
            name: "Ben",
            events: [
                {
                    start: "2020-01-21",
                    end: "2020-01-21"
                },
            ]
        },
        {
            _id: 456,
            name: "Ben",
            events: [
                {
                    start: "2020-02-01",
                    end: "2020-02-01"
                },
            ]
        },

我的群组汇总

'$group': {
        '_id': '$_id',
        'resourceName': {
            '$first': '$name',
        },
        'events': {
            '$push': "$events"
        }
    }

期望的输出

[
    {
        _id: 123,
        name: "John",
        events: [
            {
                start: "2020-01-01",
                end: "2020-01-01"
            },
            {
                start: "2020-01-01",
                end: "2020-01-01"
            },
            {
                start: "2020-01-21",
                end: "2020-01-21"
            },
        ]
    },
        {
            _id: 456,
            name: "Ben",
            events: [
                {
                    start: "2020-02-01",
                    end: "2020-02-01"
                },
                {
                    start: "2020-01-21",
                    end: "2020-01-21"
                },
            ]
        },
    ]

标签: mongodb

解决方案


使用 $unwind 展平源数组,然后使用 $addToSet 删除重复项。

数据:

cc.insert_many([{
  foo: 1,
  bar: [10, 11],
}, {
  foo: 1,
  bar: [10, 21],
}, {
  foo: 2,
  bar: [30, 31],
}])
[{"$unwind"=>"$bar"},
 {"$group"=>{"_id"=>"$foo", "bar"=>{"$addToSet"=>"$bar"}}}]

[{"_id"=>2, "bar"=>[30, 31]}, {"_id"=>1, "bar"=>[21, 10, 11]}]

推荐阅读