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

Comment calculer la différence entre les valeurs de différents documents en utilisant l'agrégation mongo?

Question difficile en principe, mais je vais rester avec le cas simplifié que vous présentez de deux documents et baser une solution autour de cela. Les concepts doivent être abstraits, mais sont plus difficiles pour les cas élargis. Possible avec le framework d'agrégation en général :

db.collection.aggregate([
    // Match the documents in a pair
    { "$match": {
        "timeMilliSec": { "$in": [ 1414590255, 1414590245 ] }
    }}

    // Trivial, just keeping an order
    { "$sort": { "timeMilliSec": -1 } },

    // Unwind the arrays
    { "$unwind": "$data" },

    // Group first and last
    { "$group": {
        "_id": "$data.name",
        "firstX": { "$first": "$data.x" },
        "lastX": { "$last": "$data.x" },
        "firstY": { "$first": "$data.y" },
        "lastY": { "$last": "$data.y" }
    }},

    // Difference on the keys
    { "$project": {
        "diff": {
            "$divide": [
                { "$subtract": [ "$firstX", "$lastX" ] },
                { "$subtract": [ "$firstY", "$lastY" ] }
            ]
        }
    }},

    // Not sure you want to take it this far
    { "$group": {
        "_id": null,
        "diffX": { 
            "$min": {
                "$cond": [
                     { "$eq": [ "$_id", "X" ] },
                     "$diff",
                     false
                 ]
            }
        },
        "diffY": { 
            "$min": {
                "$cond": [
                     { "$eq": [ "$_id", "Y" ] },
                     "$diff",
                     false
                 ]
            }
        }
    }}
])

Peut-être exagéré, pas sûr de l'intention, mais le résultat de ceci basé sur l'échantillon serait :

{ 
    "_id" : null, 
    "diffX" : 0.14285714285714285, 
    "diffY" : 0.6 
}

Ce qui correspond aux calculs.

Vous pouvez vous adapter à votre cas, mais le principe général est le suivant.

La dernière étape du "pipeline" est un peu "extrême" car il ne s'agit que de combiner les résultats en un seul document. Sinon, les résultats "X" et "Y" sont déjà obtenus en deux documents en préparation. Principalement par le $group opération avec $first et $last opérations pour trouver les éléments respectifs sur la limite de regroupement.

Les opérations suivantes dans $project en tant qu'étape de pipeline, effectue les calculs requis pour déterminer les résultats distincts. Voir les opérateurs d'agrégation pour plus de détails, en particulier $divide et $subtract .

Quoi que vous fassiez, vous suivez ce cours. Obtenez une paire "début" et "fin" sur vos deux clés. Effectuez ensuite les calculs.