MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Wie berechnet man den Unterschied zwischen Werten verschiedener Dokumente mit Mongo-Aggregation?

Im Prinzip schwierige Frage, aber ich bleibe bei dem von Ihnen vorgestellten vereinfachten Fall von zwei Dokumenten und baue darauf eine Lösung auf. Die Konzepte sollten abstrahieren, sind aber für erweiterte Fälle schwieriger. Möglich mit dem Aggregation Framework allgemein:

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

Möglicherweise übertrieben, der Absicht nicht sicher, aber die Ausgabe auf der Grundlage des Beispiels wäre:

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

Was den Berechnungen entspricht.

Sie können sich an Ihren Fall anpassen, aber das allgemeine Prinzip ist wie gezeigt.

Die letzte "Pipeline"-Phase dort ist ein wenig "extrem", da alles, was getan wird, darin besteht, die Ergebnisse in einem einzigen Dokument zusammenzufassen. Andernfalls werden die "X"- und "Y"-Ergebnisse bereits in zwei erhalten Dokumente in der Pipeline. Meistens von $group Betrieb mit $first und $last Operationen, um die entsprechenden Elemente auf der Gruppierungsgrenze zu finden.

Die nachfolgenden Operationen in $project während eine Pipelinestufe die erforderlichen Berechnungen durchführt, um die unterschiedlichen Ergebnisse zu bestimmen. Siehe Aggregationsoperatoren für weitere Details, insbesondere $divide und $subtract .

Was auch immer Sie tun, Sie folgen diesem Kurs. Holen Sie sich ein "Start"- und "Ende"-Paar auf Ihren beiden Schlüsseln. Führen Sie dann die Berechnungen durch.