如何使用mongo聚合计算不同文档的值之间的差异?

use*_*141 3 mongodb mongodb-query aggregation-framework

嗨我的mongo结构如下

{
"timemilliSec":1414590255,
"data":[
    {
    "x":23,
    "y":34,
    "name":"X"
    },
    {
    "x":32,
    "y":50,
    "name":"Y"
    }
    ]
},
{
"timemilliSec":1414590245,
"data":[
    {
    "x":20,
    "y":13,
    "name":"X"
    },
    {
    "x":20,
    "y":30,
    "name":"Y"
    }
    ]
}
Run Code Online (Sandbox Code Playgroud)

现在我想以这种方式计算第一文件和第二文件的差异以及第二到第三文件的差异,因此计算如下

diffX = ((data.x-data.x)/(data.y-data.y)) in our case ((23-20)/(34-13))
diffY = ((data.x-data.x)/(data.y-data.y)) in our case ((32-20)/(50-30))
Run Code Online (Sandbox Code Playgroud)

Nei*_*unn 6

原则上是一个棘手的问题,但我将继续介绍你提出的两个文件的简化案例,并以此为基础提出解决方案.概念应该是抽象的,但对于扩展的案例来说更难.通常可以使用聚合框架:

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
                 ]
            }
        }
    }}
])
Run Code Online (Sandbox Code Playgroud)

可能过分夸大,不确定意图,但基于样本的输出将是:

{ 
    "_id" : null, 
    "diffX" : 0.14285714285714285, 
    "diffY" : 0.6 
}
Run Code Online (Sandbox Code Playgroud)

哪个与计算相匹配.

您可以适应您的情况,但一般原则如图所示.

最后一个"管道"阶段有一点"极端",因为所做的就是将结果合并到一个文档中.否则,已在管道中的两个文档中获得"X"和"Y"结果.主要通过$group操作$first$last操作来找到分组边界上的各个元素.

$project作为管道阶段的后续操作执行所需的数学运算以确定不同的结果.看到聚集运营商更多的细节,特别是$divide$subtract.

无论你做什么,你都遵循这个课程.在两把钥匙上获得"开始"和"结束"对.然后执行计算.