To dělá to, co potřebujete. Časy v datech jsem normalizoval, takže se seskupují (Mohli byste udělat něco takového). Cílem je $group
a stiskněte time
's a total
's do samostatných polí. Poté $unwind
time
pole a vytvořili jste kopii totals
pole pro každý time
dokument. Poté můžete vypočítat runningTotal
(nebo něco jako klouzavý průměr) z pole obsahujícího všechna data pro různé časy. 'index' generovaný $unwind
je index pole pro total
odpovídající tomuto time
. Je důležité $sort
před $unwind
ing, protože to zajišťuje, že pole jsou ve správném pořadí.
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 ] } ] } },
}
},
]
);
Použil jsem něco podobného na kolekci s ~ 80 000 dokumenty, které dohromady tvoří 63 výsledků. Nejsem si jistý, jak dobře to bude fungovat na větších kolekcích, ale zjistil jsem, že provádění transformací (projekce, manipulace s poli) na agregovaných datech se nezdá mít velké náklady na výkon, jakmile se data zmenší na zvládnutelnou velikost.