[英]Mongo aggregations with multiple match or union
I am trying to aggregate some information coming from different devices. 我正在尝试汇总来自不同设备的一些信息。 Given a set of device ids, I'd like to count the number of times values occur. 给定一组设备ID,我想计算值出现的次数。 The bit that I am struggling with is we only want to work on each device's last report. 我苦苦挣扎的一点是,我们只想处理每个设备的最新报告。
For example, 4 devices have stored hundreds of thousands of reports in the report collection. 例如,有4台设备已在报告集中存储了数十万个报告。 The reports tells us if there was a networkDown event or not (boolean). 这些报告告诉我们是否存在networkDown事件(布尔值)。 I want to count the number of times networkDown is true or false within the 4 device's last reports. 我想计算4个设备的上次报告中networkDown为true或false的次数。
I am using mongoDB 2.4.4 我正在使用mongoDB 2.4.4
A report looks similar to this: 报告看起来类似于此:
{
"_id":ObjectId("52571500fa1fc70437000001"),
"device_id" : ObjectId("51f14f9f9809c4404f00000a"),
"payload":{
"name":"Status",
"properties":{
"property":{
"deviceIdentifier":"My Device",
"networkDown":"false"
}
}
},
"updated_at":ISODate("2013-10-10T20:58:40.674Z"),
"created_at":ISODate("2013-10-10T20:58:40.674Z")
}
The group I can do on all records for all 4 devices. 我可以在所有4个设备的所有记录上执行的组。 Say, 说,
db.report.aggregate(
[
{ $match: { device_id:
{
$in:
[
ObjectId("51f14f9f9809c4404f00000a"),
ObjectId("523ab68a9809c4e490000059"),
ObjectId("522f37b89809c4e8cf000033"),
ObjectId("522f38019809c4ae070000d3")
]
}
}
},
{ $group: { _id: "$payload.properties.property.networkDown", total: { $sum: 1 } } }
])
{
"result" : [
{
"_id" : "true",
"total" : 2
},
{
"_id" : "false",
"total" : 278539
}
],
"ok" : 1
}
But how can I limit the query to only work on the last report for each device? 但是,如何限制查询仅在每个设备的最后一个报告上起作用?
Thanks for looking! 感谢您的光临!
You will have first sort on the basis of {updated_at:1}
.Then group by device_id and use the $last operator to take only the last networkDown field since the documents are sorted . 您将首先基于{updated_at:1}
排序。然后按device_id进行分组,并使用$ last运算符仅采用最后一个networkDown字段,因为对文档进行了排序。 Then do another group on the networkDown property. 然后在networkDown属性上执行另一个组。 I know its a little complicated , but here's the query: 我知道它有点复杂,但这是查询:
db.reports.aggregate(
[
{ $match: { device_id:
{
$in:
[
ObjectId("51f14f9f9809c4404f00000a"),
ObjectId("523ab68a9809c4e490000059"),
ObjectId("522f37b89809c4e8cf000033"),
ObjectId("522f38019809c4ae070000d3")
]
}
}
},
{$sort:{updated_at:1}},
{$group:
{_id:"$device_id",
networkDown:{$last:"$payload.properties.property.networkDown"}
}
},
{$group:{_id:"$networkDown",count:{$sum:1}}}
])
I haven't tried it properly , but it should work.Let me know in case of any propblem 我没有正确尝试过,但是应该可以。如果有任何问题,请通知我
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.