我尝试使用MongoDB Aggregation来分析数据。目前我有以下代码:
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"
},
...
]
你能帮帮我吗?感谢。
答案 0 :(得分:2)
在这种情况下,您似乎需要$first
和$last
运算符。这些通常在$sort
之后有意义,除非您完全确定所有文档的日期顺序都在增加:
db.events.aggregate([
{ "$sort": { "createdAt": 1 } },
{ "$group": {
"_id": {
"asset": "$asset",
"day": { "$dayOfYear": "$createdAt" },
"year": { "$year": "$createdAt" }
},
"firstOdometer": { "$first": "$odometer" },
"lastOdometer": { "$last": "$odometer" },
"firstFuel": { "$first": "$fuel" },
"lastFuel": { "$last": "$fuel" }
}},
{ "$project": {
"_id": 1,
"diffOdometer": { "$subtract": [ "$lastOdometer", "$firstOdometer" ] },
"diffFuel": { "$subtract": [ "$lastFuel", "$firstFuel" ] }
}}
])
然后当然,在从分组中获得这些值之后,使用$subtract
运算符计算出“第一”和“最后”读数的“差异”。
不确定“点火”开/关事件与您的数据样本有什么相关性,但在这种情况下,它似乎不是“完全”的逻辑点,但当然会添加任何相关的$match
标准管道的第一阶段。同时注意到放置$project
管道阶段没有特别的优势。在这种情况下,这可能不会“减少”管道中的字段。管道“优化器”将仅考虑$group
中指定的字段对其进行排序。从上面开始,它会从一开始就这样做,因此在$ match之后,只有四个字段会出现在管道文档中。
当然,这并没有考虑到“重新加油”,只是假设你开始使用燃料并以燃料结束而消耗的是差异。考虑到这一点,你可能会有一个“重新加油”的事件类型,你可以从中获得总投入量。就像这样:
db.events.aggregate([
{ "$sort": { "createdAt": 1 } },
{ "$group": {
"_id": {
"asset": "$asset",
"day": { "$dayOfYear": "$createdAt" },
"year": { "$year": "$createdAt" }
},
"firstOdometer": { "$first": "$odometer" },
"lastOdometer": { "$last": "$odometer" },
"firstFuel": { "$first": "$fuel" },
"lastFuel": { "$last": "$fuel" },
"reFuelled": {
"$sum": { "$cond": [
{ "$eq": [ "codename", "REFUEL" ] },
"$filled",
0
] }
}
}},
{ "$project": {
"_id": 1,
"diffOdometer": { "$subtract": [ "$lastOdometer", "$firstOdometer" ] },
"diffFuel": {
"$subtract": [
"$lastFuel",
{ "$add": [ "$firstFuel", "$reFuelled" ] }
]
}
}}
])
或者无论如何都是这样的。
简短案例是获取“开始”和“结束”数据,然后将数学应用于这些点。