Создание объектов из массива объектов в сгруппированной агрегации монго

#mongodb #mongodb-query #aggregation-framework #nosql-aggregation

Вопрос:

Я писал конвейер агрегирования, чтобы показать обобщенную версию данных из коллекции.

Образец структуры документа:

 {
    _id: 'abcxyz',
    eventCode: 'EVENTCODE01',
    eventName: 'SOMEEVENT',
    units: 1,
    rate: 2,
    cost: 2,
    distribution: [
        {
            startDate: 2021-05-31T04:00:00.000 00:00
            units: 1
        }
    ]
}
 

Я сгруппировал его и объединил дистрибутив в один список с $unwind шагом до $group :

 [
    $unwind: {
        path: '$distribution',
        preserveNullAndEmptyArrays: false
    },
    $group: {
        _id: {
            eventName: '$eventName',
            eventCode: '$eventCode'
        },
        totalUnits: {
            $sum: '$units'
        },
        distributionList: {
            $push: '$distribution'
        },
        perUnitRate: {
            $avg: '$rate'
        },
        perUnitCost: {
            $avg: '$cost'
        }
    }
]
 

Пример Вывода:

 {
    _id: {
        eventName: 'EVENTNAME101'
        eventCode: 'QQQ'
    },
    totalUnits: 7,
    perUnitRate: 2,
    perUnitCost: 2,
    distributionList: [
        {
            startDate: 2021-05-31T04:00:00.000 00:00,
            units: 1
        },
        {
            startDate: 2021-05-31T04:00:00.000 00:00,
            units: 1
        },
        {
            startDate: 2021-06-07T04:00:00.000 00:00,
            units: 1
        }
    ]
}
 

Я застрял на следующем шаге; Я хочу объединить distributionList их в новый список без повторения startDate .

Пример: Поскольку первые 2 объекта списка рассылки имеют одинаковую дату начала, в выводе должен быть один объект с суммой единиц:

Ожидаемый:

 {
    _id: {
        eventName: 'EVENTNAME101'
        eventCode: 'QQQ'
    },
    totalUnits: 7,
    perUnitRate: 2,
    perUnitCost: 2,
    newDistributionList: [
        {
            startDate: 2021-05-31T04:00:00.000 00:00,
            units: 2 //units summed for first 2 objects
        },
        {
            startDate: 2021-06-07T04:00:00.000 00:00,
            units: 1
        }
    ]
}
 

Я не мог использовать $unwind или $bucket , как я намереваюсь, сохранить группировку, которую я делал на предыдущих шагах ( $group ).

Могу ли я получить предложения или другой подход, если это не кажется точным?

Ответ №1:

Возможно, вы захотите сделать первое $group на eventName, eventCode, distribution.startDate уровне. Затем вы можете $group снова на eventName, eventCode уровне и использовать $first , чтобы сохранить свои исходные $group поля.

Вот игровая площадка Mongo, чтобы показать идею для вашей справки.