Dette gør, hvad du har brug for. Jeg har normaliseret tiderne i dataene, så de grupperer sig (Du kunne gøre sådan noget). Ideen er at $group
og tryk på time
's og total
's i separate arrays. Derefter $unwind
time
array, og du har lavet en kopi af totals
array for hver time
dokument. Du kan derefter beregne runningTotal
(eller noget som det rullende gennemsnit) fra arrayet, der indeholder alle data for forskellige tidspunkter. 'Indekset' genereret af $unwind
er matrixindekset for total
svarende til det time
. Det er vigtigt at $sort
før $unwind
ing, da dette sikrer, at arrays er i den rigtige rækkefølge.
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 ] } ] } },
}
},
]
);
Jeg har brugt noget lignende på en samling med ~80.000 dokumenter, samlet til 63 resultater. Jeg er ikke sikker på, hvor godt det vil fungere på større samlinger, men jeg har fundet ud af, at udførelse af transformationer (projektioner, array-manipulationer) på aggregerede data ikke ser ud til at have store ydeevneomkostninger, når først dataene er reduceret til en håndterbar størrelse.