To robi to, czego potrzebujesz. Znormalizowałem czasy w danych, aby się grupowały (możesz zrobić coś takiego). Chodzi o to, aby $group i naciśnij time i total jest w osobnych tablicach. Następnie $unwind time tablicę i zrobiłeś kopię totals tablica dla każdego time dokument. Następnie możesz obliczyć runningTotal (lub coś w rodzaju średniej kroczącej) z tablicy zawierającej wszystkie dane dla różnych czasów. „Indeks” wygenerowany przez $unwind jest indeksem tablicy dla total odpowiadające temu time . Ważne jest, aby $sort przed $unwind ing, ponieważ zapewnia to, że tablice są we właściwej kolejności.
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 ] } ] } },
}
},
]
);
Użyłem czegoś podobnego w kolekcji zawierającej ~80 000 dokumentów, agregując do 63 wyników. Nie jestem pewien, jak dobrze to będzie działać na większych kolekcjach, ale odkryłem, że wykonywanie transformacji (rzutów, manipulacji tablicami) na zagregowanych danych nie wydaje się mieć dużego kosztu wydajności, gdy dane zostaną zredukowane do możliwego do zarządzania rozmiaru.