sql >> Base de Datos >  >> NoSQL >> MongoDB

Agregación de MongoDB:calcule los totales acumulados a partir de la suma de las filas anteriores

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.