MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Agregação do MongoDB:Calcular os totais em execução da soma das linhas anteriores


Isso faz o que você precisa. Eu normalizei os tempos nos dados para que eles se agrupassem (você poderia fazer algo assim). A ideia é $group e empurre o time 's e total 's em arrays separados. Então $unwind a time array, e você fez uma cópia dos totals array para cada time documento. Você pode então calcular o runningTotal (ou algo como a média móvel) do array contendo todos os dados para tempos diferentes. O 'índice' gerado por $unwind é o índice do array para o total correspondente a essa time . É importante $sort antes de $unwind ing, pois isso garante que as matrizes estejam na ordem correta.
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 ] } ] } },
            }
        },
    ]
);

Usei algo semelhante em uma coleção com ~80.000 documentos, agregando 63 resultados. Não tenho certeza de como isso funcionará em coleções maiores, mas descobri que realizar transformações (projeções, manipulações de matriz) em dados agregados não parece ter um grande custo de desempenho quando os dados são reduzidos a um tamanho gerenciável.