Questo fa ciò di cui hai bisogno. Ho normalizzato i tempi nei dati in modo che si raggruppino (potresti fare qualcosa del genere). L'idea è di $group
e premi il time
's e total
's in array separati. Quindi $unwind
il time
array e hai fatto una copia dei totals
matrice per ogni time
documento. Puoi quindi calcolare il runningTotal
(o qualcosa come la media mobile) dall'array contenente tutti i dati per tempi diversi. L'"indice" generato da $unwind
è l'indice dell'array per il total
corrispondente a quel time
. È importante $sort
prima di $unwind
ing poiché ciò garantisce che gli array siano nell'ordine corretto.
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 ] } ] } },
}
},
]
);
Ho usato qualcosa di simile su una raccolta con circa 80.000 documenti, aggregando a 63 risultati. Non sono sicuro di come funzionerà bene su raccolte più grandi, ma ho scoperto che l'esecuzione di trasformazioni (proiezioni, manipolazioni di array) su dati aggregati non sembra avere un costo elevato in termini di prestazioni una volta che i dati vengono ridotti a una dimensione gestibile.