Cela fait ce dont vous avez besoin. J'ai normalisé les heures dans les données afin qu'elles se regroupent (vous pourriez faire quelque chose comme ça). L'idée est de $group
et poussez le time
et total
's dans des tableaux séparés. Puis $unwind
le time
tableau, et vous avez fait une copie des totals
tableau pour chaque time
document. Vous pouvez ensuite calculer le runningTotal
(ou quelque chose comme la moyenne mobile) du tableau contenant toutes les données à des moments différents. L''index' généré par $unwind
est l'index du tableau pour le total
correspondant à cette time
. Il est important de $sort
avant $unwind
car cela garantit que les tableaux sont dans le bon ordre.
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 ] } ] } },
}
},
]
);
J'ai utilisé quelque chose de similaire sur une collection d'environ 80 000 documents, regroupant 63 résultats. Je ne sais pas dans quelle mesure cela fonctionnera sur de plus grandes collections, mais j'ai constaté que l'exécution de transformations (projections, manipulations de tableaux) sur des données agrégées ne semble pas avoir un coût de performance important une fois que les données sont réduites à une taille gérable.