MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Agrégation MongoDB :calcule les totaux cumulés à partir de la somme des lignes précédentes

Cela fait ce dont vous avez besoin. J'ai normalisé les heures dans les données afin qu'elles se regroupent (vous pourriez faire quelque chose comme ça). L'idée est de $group et poussez le time et total 's dans des tableaux séparés. Puis $unwind le time tableau, et vous avez fait une copie des totals tableau pour chaque time document. Vous pouvez ensuite calculer le runningTotal (ou quelque chose comme la moyenne mobile) du tableau contenant toutes les données à des moments différents. L''index' généré par $unwind est l'index du tableau pour le total correspondant à cette time . Il est important de $sort avant $unwind car cela garantit que les tableaux sont dans le bon ordre.

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 ] } ] } },
            }
        },
    ]
);

J'ai utilisé quelque chose de similaire sur une collection d'environ 80 000 documents, regroupant 63 résultats. Je ne sais pas dans quelle mesure cela fonctionnera sur de plus grandes collections, mais j'ai constaté que l'exécution de transformations (projections, manipulations de tableaux) sur des données agrégées ne semble pas avoir un coût de performance important une fois que les données sont réduites à une taille gérable.