我正在处理从IoT设备不断收到的一系列测量。每个度量都具有以下文档架构:
{
"_id" : ObjectId("58e3c885713c09001a0c2125"),
"recvTime" : ISODate("2017-04-18T16:23:38.928Z"),
"entityId" : "t01",
"entityType" : "Thing",
"attrName" : "Temperature",
"attrType" : "text",
"attrValue" : "32.5"
}
根据设备的编程方式,对于设备的每个属性,我都有不同的测量值。当设备每N秒发送一次数据时,每N秒插入的设备数量与文件中的属性一样多。在“recvTime”字段中具有相同timeinstant的所有文档。
我的问题是我想要在单个文档中折叠对应于特定时间的所有测量数据。这样我每隔N秒就会有一个包含所有设备测量值的文档,而不是我设备上的属性文件。
例如,有两个属性温度和压力,我想改变这个:
{
"_id" : ObjectId("58e3c885713c09001a0c2125"),
"recvTime" : ISODate("2017-04-18T16:23:38.928Z"),
"entityId" : "t01",
"entityType" : "Thing",
"attrName" : "Temperature",
"attrType" : "text",
"attrValue" : "32.5"
},
{
"_id" : ObjectId("58e3c885713c09001a0c2125"),
"recvTime" : ISODate("2017-04-18T16:23:38.928Z"),
"entityId" : "t01",
"entityType" : "Thing",
"attrName" : "Preassure",
"attrType" : "text",
"attrValue" : "512"
}
进入这样的事情:
{
"_id" : ObjectId("58e3c885713c09001a0c2125"),
"recvTime" : ISODate("2017-04-18T16:23:38.928Z"),
"entityId" : "t01",
"entityType" : "Thing",
"Temperature" : "32.5",
"Preassure" : "512"
}
有没有办法只使用Mongo Aggregation Framework查询?我宁愿不在应用程序中这样做。
提前致谢。
您可以在3.6中使用以下聚合。
$group
将所有与$$ROOT
相同的时间戳文档分组到$push
完整文档。
$objectToArray
与$filter
过滤需要重命名的密钥,然后$mergeObjects
与$arrayToObject
在$reduce
运算符中合并分组文档。
$replaceRoot
将合并文件推广到顶级水平。
[{"$group":{
"_id":"$recvTime",
"data":{"$push":"$$ROOT"}
}},
{"$replaceRoot":{
"newRoot":{
"$reduce":{
"input":"$data",
"initialValue":{},
"in":{
"$mergeObjects":[
{"$arrayToObject":{
"$filter":{
"input":{"$objectToArray":"$$this"},
"cond":{"$not":{"$in":["$$this.k",["attrName","attrValue","attrType"]]}}
}
}},
{"$arrayToObject":[[{"k":"$$this.attrName","v":"$$this.attrValue"}]]},
"$$value"
]
}
}
}
}}]