#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, чтобы показать идею для вашей справки.