sql >> Base de Datos >  >> NoSQL >> MongoDB

¿Cómo calcular la diferencia entre los valores de diferentes documentos utilizando la agregación de mongo?

Es una pregunta difícil en principio, pero me quedaré con el caso simplificado que presentas de dos documentos y basaré una solución en eso. Los conceptos deben abstraerse, pero son más difíciles para casos expandidos. Posible con el marco de agregación en general:

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

Posiblemente exagerado, no estoy seguro de la intención, pero el resultado de esto basado en la muestra sería:

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

Que coincide con los cálculos.

Puede adaptarse a su caso, pero el principio general es el que se muestra.

La última etapa de "tubería" es un poco "extrema", ya que todo lo que se hace es combinar los resultados en un solo documento. De lo contrario, los resultados "X" e "Y" ya se obtienen en dos documentos en trámite. Principalmente por el $group operación con $first y $last operaciones para encontrar los elementos respectivos en el límite de agrupación.

Las operaciones posteriores en $project como una etapa de canalización realiza las operaciones matemáticas necesarias para determinar los distintos resultados. Consulte los operadores de agregación para más detalles, particularmente $divide y $subtract .

Hagas lo que hagas, sigue este curso. Obtenga un par de "inicio" y "fin" en sus dos claves. Luego realice los cálculos.