11
votes

Agrégation de MongoDB: calculer les totaux d'exécution de la somme des rangées précédentes

Exemples de documents:

{
 time: "2013-10-10"
 total: 3,
 runningTotal: 3
},
{
 time: "2013-10-11"
 total: 7,
 runningTotal: 10 
},
{
 time: "2013-10-12"
 total: 5,
 runningTotal: 15
}


4 commentaires

Pouvez-vous garder un total en cours au fur et à mesure que vous allez. Ce serait le plus simple et le plus efficace, d'autant plus que les données ne changent pas. Le cadre d'agrégation serait un moyen assez coûteux de calculer ce type de données statiques à la volée.


Il n'y a aucun moyen de le faire avec le cadre d'agrégation actuellement.


@Cirrus merci pour la réponse. Je ne suis pas tout à fait sûr de voir comment ça va ...


Eh bien, je pense que cela impliquerait plusieurs requêtes agrégées. Vous ne pouviez pas le faire dans une commande. Mais en calculant que vous avez suivi, cela signifie simplement ajouter un autre champ à chaque entrée pour garder une trace du total exécutant. Selon votre application, vous pouvez le faire lorsque vous écrivez des données ou vous pouvez exécuter une tâche d'arrière-plan pour le calculer à la fin de chaque journée. Mais cela suppose que vous écrivez les données comme vous le suivez, je ne sais pas où vient vos données. Si les données sont déjà là, vous devrez exécuter une requête pour chaque jour et stocker cela ailleurs.


3 Réponses :


11
votes

Cela fait ce dont vous avez besoin. J'ai normalisé les temps dans les données afin qu'ils se regroupent ensemble (vous pouvez faire quelque chose comme Ceci ). L'idée est de $ Group CODE> et appuyez sur l'heure code> S et Total code> dans des tableaux séparés. Ensuite, $ RESTAIN CODE> THE CODE> TIME CODE> Tableau et vous avez effectué une copie du tableau CODE> TOTALES CODE> pour chaque TIME CODE> DOCUMENT. Vous pouvez ensuite calculer le windowtotal code> (ou quelque chose comme la moyenne roulante) de la matrice contenant toutes les données de différentes périodes. "Index" généré par $ result code> est l'index de tableau pour le total code> correspondant à ce heure code>. Il est important de $ trier code> avant $ Doulez-vous code> car cela garantit que 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 ] } ] } },
            }
        },
    ]
);


0 commentaires

3
votes

Voici une autre approche

pipeline p> xxx pré>

collection p> xxx pré>

résultat p>

{ "_id" : "2013-10-10", "value" : 3, "runningTotal" : 3 }
{ "_id" : "2013-10-11", "value" : 7, "runningTotal" : 10 }
{ "_id" : "2013-10-12", "value" : 5, "runningTotal" : 15 }
> 


0 commentaires

3
votes

Voici une solution sans pousser les documents précédents dans un nouveau tableau, puis les traiter. (Si le tableau devient trop gros, vous pouvez dépasser la limite maximale de taille du document BSON, le 16 Mo.)

Calculer les totaux de fonctionnement est aussi simple que: P>

{ "_id" : "2013-10-10", "value" : 3, "running_total" : 3 }
{ "_id" : "2013-10-11", "value" : 7, "running_total" : 10 }
{ "_id" : "2013-10-12", "value" : 5, "running_total" : 15 }


0 commentaires