У меня есть коллекция в моей базе данных MongoDB, в которой хранятся длительности для людей, которые находятся в группах, это выглядит примерно так:
[{
"_id": "5c378eecd11e570240a9b0ac",
"state": "DRAFT",
"groupId": "5c378eebd11e570240a9ae49",
"personId": "5c378eebd11e570240a9aee1",
"date": "2019-01-07T00:00:00.000Z",
"duration": 480,
"__v": 0
},
{
"_id": "5c378eecd11e570240a9b0bb",
"state": "DRAFT",
"groupId": "5c378eebd11e570240a9ae58",
"personId": "5c378eebd11e570240a9aeac",
"date": "2019-01-07T00:00:00.000Z",
"duration": 480,
"__v": 0
},
{
"_id": "5c378eecd11e570240a9b0c5",
"state": "DRAFT",
"groupId": "5c378eebd11e570240a9ae3e",
"personId": "5c378eebd11e570240a9aef6",
"date": "2019-01-07T00:00:00.000Z",
"duration": 480,
"__v": 0
}]
Я хотел бы иметь возможность выполнить агрегатный запрос, который возвращает коллекцию personIds
и duration
, сгруппированных в день с соответствующим groupId
, который будет выглядеть следующим образом:
[{
"personId": "5c378eebd11e570240a9aee1",
"time": [{
"date": "2019-01-07T00:00:00.000Z",
"entries": [{
"groupId": "5c378eebd11e570240a9ae49",
"duration": 480,
"state": "DRAFT"
}]
}]
}, {
"personId": "5c378eebd11e570240a9aeac",
"time": [{
"date": "2019-01-07T00:00:00.000Z",
"entries": [{
"groupId": "5c378eebd11e570240a9ae58",
"duration": 480,
"state": "DRAFT"
}]
}]
}, {
"personId": "5c378eebd11e570240a9aef6",
"time": [{
"date": "2019-01-07T00:00:00.000Z",
"entries": [{
"groupId": "5c378eebd11e570240a9ae3e",
"duration": 480,
"state": "DRAFT"
}]
}]
}]
Пока что я написал следующую агрегацию (я использую Mongoose, отсюда и синтаксис):
Time.aggregate()
.match({ date: { $gte: new Date(start), $lte: new Date(end) } })
.group({
_id: '$personId',
time: { $push: { date: '$date', duration: '$duration', state: '$state' } },
})
.project({ _id: false, personId: '$_id', time: '$time' })
, который возвращает следующее:
[{
"personId": "5c378eebd11e570240a9aed1",
"time": [{
"date": "2019-01-11T00:00:00.000Z",
"duration": 480,
"state": "DRAFT"
}, {
"date": "2019-01-11T00:00:00.000Z",
"duration": 480,
"state": "DRAFT"
}
// ...
}]
Надеюсь, вы видите, что duration
сгруппированы по personId
, но я не смог выяснить, как применить другую группировку к массиву time
, так как date
дублируются, если personId
имеет более одного duration
на указанную дату.
Можно ли сгруппировать по идентификатору, идентификатору, передать в массив, а затем сгруппировать значения в этом массиве в виде агрегации, или вместо этого моему приложению потребуется отобразить / уменьшить результаты?