MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Aggregazione MongoDB:calcola i totali parziali dalla somma delle righe precedenti

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.