Това прави това, от което се нуждаете. Нормализирах времената в данните, така че да се групират заедно (можете да направите нещо подобно). Идеята е $group
и натиснете time
's и total
е в отделни масиви. След това $unwind
time
масив и сте направили копие на totals
масив за всяко time
документ. След това можете да изчислите runningTotal
(или нещо като подвижната средна стойност) от масива, съдържащ всички данни за различни времена. „Индексът“, генериран от $unwind
е индексът на масива за total
съответстващ на това time
. Важно е да $sort
преди $unwind
тъй като това гарантира, че масивите са в правилния ред.
db.temp.aggregate(
[
{
'$group': {
'_id': '$time',
'total': { '$sum': '$value' }
}
},
{
'$sort': {
'_id': 1
}
},
{
'$group': {
'_id': 0,
'time': { '$push': '$_id' },
'totals': { '$push': '$total' }
}
},
{
'$unwind': {
'path' : '$time',
'includeArrayIndex' : 'index'
}
},
{
'$project': {
'_id': 0,
'time': { '$dateToString': { 'format': '%Y-%m-%d', 'date': '$time' } },
'total': { '$arrayElemAt': [ '$totals', '$index' ] },
'runningTotal': { '$sum': { '$slice': [ '$totals', { '$add': [ '$index', 1 ] } ] } },
}
},
]
);
Използвал съм нещо подобно за колекция с ~80 000 документа, обобщавайки до 63 резултата. Не съм сигурен колко добре ще работи при по-големи колекции, но открих, че извършването на трансформации (проекции, манипулации на масиви) върху агрегирани данни изглежда няма да има големи разходи за производителност, след като данните са намалени до управляем размер.