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.