Esto hace lo que necesitas. He normalizado los tiempos en los datos para que se agrupen (podrías hacer algo como esto). La idea es $group
y presiona el time
y total
's en arreglos separados. Luego $unwind
el time
matriz, y ha hecho una copia de los totals
matriz para cada time
documento. A continuación, puede calcular el runningTotal
(o algo así como el promedio móvil) de la matriz que contiene todos los datos para diferentes momentos. El 'índice' generado por $unwind
es el índice de matriz para el total
correspondiente a esa time
. Es importante $sort
antes de $unwind
ing ya que esto asegura que las matrices estén en el orden correcto.
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 ] } ] } },
}
},
]
);
He usado algo similar en una colección con ~80 000 documentos, sumando 63 resultados. No estoy seguro de qué tan bien funcionará en colecciones más grandes, pero descubrí que realizar transformaciones (proyecciones, manipulaciones de matrices) en datos agregados no parece tener un gran costo de rendimiento una vez que los datos se reducen a un tamaño manejable.