MongoDB使用聚合框架计算分组后的差异

MongoDB使用聚合框架计算分组后的差异,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我试图使用MongoDB聚合来分析数据。目前我有以下代码: db.events.aggregate( [ { $match: { $or: [ {codename: "IGNITION_ON"}, {codename: "IGNITION_OFF"} ] } },

我试图使用MongoDB聚合来分析数据。目前我有以下代码:

db.events.aggregate(
    [
        {
            $match: {
                $or: [
                    {codename: "IGNITION_ON"},
                    {codename: "IGNITION_OFF"}
                ]
            }
        },
        {
            $project: {
                asset: 1,
                codename: 1,
                createdAt: 1,
                fuel: 1,
                odometer: 1
            }
        },
        {
            $group: {
                _id: {
                    asset: "$asset",
                    codename: "$codename",
                    day: { $dayOfYear: "$createdAt"}, 
                    year: { $year: "$createdAt" }
                },
                sumOdometer: {$sum: "$odometer"},
                sumFuel: {$sum: "$fuel"}
            }
        }
    ]
)
上面的代码检索所有车辆的所有点火开关打开和关闭,并计算它们一天内的里程表和燃油的总和。问题是我需要获得以下输出,即每辆车在一天内的燃油和里程表(距离和消耗)之差

[
    {
        "asset" : ObjectId("540e5d8e44616e1c8b260000"), 
        "day" : 213, 
        "year" : 2014 
        "diffOdometer" : "5",
        "diffFuel" : "10"
    },
    ...
]

你能帮我吗?谢谢。

在这种情况下,您似乎需要and运算符。除非您完全确定所有文档都已按递增日期顺序排列,否则这些通常在a之后才有意义:

db.events.aggregate([
{“$sort”:{“createdAt”:1},
{“$组”:{
“_id”:{
“资产”:“$asset”,
“日”:{“$dayOfYear”:“$createdAt”},
“年”:{“$year”:“$createdAt”}
},
“第一里程表”:{“$first”:“$odometer”},
“last里程表”:{“$last”:“$里程表”},
“firstFuel”:{“$first”:“$fuel”},
“lastFuel”:{“$last”:“$fuel”}
}},
{“$project”:{
“_id”:1,
“Diff里程表”:{“$subtract”:[“$Last里程表”,“$First里程表”]},
“diffFuel”:{“$subtract”:[“$lastFuel”,“$firstFuel”]}
}}
])
当然,在通过分组获得这些值后,使用运算符计算出“第一次”和“最后一次”读数的“差异”

不确定“点火”开/关事件与您的数据样本有什么关联,但在本例中,“总计”似乎不是一个合乎逻辑的点,但当然,添加任何相关标准作为管道的第一阶段。还要注意的是,像您这样放置管道阶段并没有什么特殊的优势。这并不像您在本例中所想的那样“减少”管道中的字段。管道“优化器”将通过只考虑中指定的字段来进行排序。从上面可以看出,它将从一开始就这样做,因此在$match之后,管道文档中只会使用四个字段

当然,这并没有考虑到“重新加油”,只是假设你从燃油开始,到燃油结束,消耗的是不同的。考虑到这一点,你可能会有一个“再燃料”事件类型,从中你可以得到总共投入了多少。像这样:

db.events.aggregate([
{“$sort”:{“createdAt”:1},
{“$组”:{
“_id”:{
“资产”:“$asset”,
“日”:{“$dayOfYear”:“$createdAt”},
“年”:{“$year”:“$createdAt”}
},
“第一里程表”:{“$first”:“$odometer”},
“last里程表”:{“$last”:“$里程表”},
“firstFuel”:{“$first”:“$fuel”},
“lastFuel”:{“$last”:“$fuel”},
“加油”:{
“$sum”:{“$cond”:[
{“$eq”:[“代码名”,“加油”]},
“$filled”,
0
] }
}
}},
{“$project”:{
“_id”:1,
“Diff里程表”:{“$subtract”:[“$Last里程表”,“$First里程表”]},
“diffFuel”:{
“$subtract”:[
“$lastFuel”,
{“$add”:[“$firstFuel”,“$refelled”]}
] 
}
}}
])
或者至少是沿着这些路线


简短的例子是获取“开始”和“结束”数据,然后将数学应用于这些点。

在这种情况下,似乎需要and运算符。除非您完全确定所有文档都已按递增日期顺序排列,否则这些通常在a之后才有意义:

db.events.aggregate([
{“$sort”:{“createdAt”:1},
{“$组”:{
“_id”:{
“资产”:“$asset”,
“日”:{“$dayOfYear”:“$createdAt”},
“年”:{“$year”:“$createdAt”}
},
“第一里程表”:{“$first”:“$odometer”},
“last里程表”:{“$last”:“$里程表”},
“firstFuel”:{“$first”:“$fuel”},
“lastFuel”:{“$last”:“$fuel”}
}},
{“$project”:{
“_id”:1,
“Diff里程表”:{“$subtract”:[“$Last里程表”,“$First里程表”]},
“diffFuel”:{“$subtract”:[“$lastFuel”,“$firstFuel”]}
}}
])
当然,在通过分组获得这些值后,使用运算符计算出“第一次”和“最后一次”读数的“差异”

不确定“点火”开/关事件与您的数据样本有什么关联,但在本例中,“总计”似乎不是一个合乎逻辑的点,但当然,添加任何相关标准作为管道的第一阶段。还要注意的是,像您这样放置管道阶段并没有什么特殊的优势。这并不像您在本例中所想的那样“减少”管道中的字段。管道“优化器”将通过只考虑中指定的字段来进行排序。从上面可以看出,它将从一开始就这样做,因此在$match之后,管道文档中只会使用四个字段

当然,这并没有考虑到“重新加油”,只是假设你从燃油开始,到燃油结束,消耗的是不同的。考虑到这一点,你可能会有一个“再燃料”事件类型,从中你可以得到总共投入了多少。像这样:

db.events.aggregate([
{“$sort”:{“createdAt”:1},
{“$组”:{
“_id”:{
“资产”:“$asset”,
“日”:{“$dayOfYear”:“$createdAt”},
“年”:{“$year”:“$createdAt”}
},
“第一里程表”:{“$first”:“$odometer”},
“last里程表”:{“$last”:“$里程表”},
“firstFuel”:{“$first”:“$fuel”},
“lastFuel”:{“$last”:“$fuel”},
“加油”:{
“$sum”:{“$cond”:[
{“$eq”:[“代码名”,“加油”]},
“$filled”,
0
] }
}
}},
{“$proj