如何将多个MongoDB文档合并为一个?

时间:2017-12-18 17:10:40

标签: mongodb aggregation-framework

我正在处理从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秒插入的设备数量与文件中的属性一样多。所有具有相同timeinstant的文档在" recvTime"字段。

我的问题是我想要折叠与单个文档中特定时间相对应的所有测量数据。这样我每隔N秒就会有一个包含所有设备测量值的文档,而不是我设备上的属性文件。

例如,有两个属性温度 preassure 我想转换它:

{
    "_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查询?我宁愿不必在申请中这样做。

提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以在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"
           ]
       }
     }
   }
}}]