$ unwind后按内部数组元素分组

时间:2017-08-29 00:55:21

标签: mongodb mongodb-query aggregation-framework

我有以下时间序列数据存储在mongodb

 { 
   "_id" : ObjectId("59a46062e1aeb958a712490e"),
   "channelName" : "ABC", 
   "rtData" : [ 
   { 
      "ts" : ISODate("2017-08-28T18:26:42.837Z"), 
      "data" : [ 676.297664, 676.297664 ] 
   },
   { 
      "ts" : ISODate("2017-08-28T18:27:42.837Z"), 
      "data" : [ 724.297664, 676.297664 ] 
   },
   { 
      "ts" : ISODate("2017-08-28T18:29:42.837Z"), 
      "data" : [ 878.297, 676.297 ] 
   } 
  ]
 }

我想在小时基于ts字段对数据进行分组,并获取该小时的rtData的第一个元素。 这是我试过的

db.channels.aggregate( [ {$match: {"channelName": "ABC"} }, { $unwind : "$rtData" }, { $group : {_id: { $hour: "$rtData.ts" }, ucast: { $sum: $rtData.data[0]} }

但是上面的代码给了我以下输出

{ "_id" : 28, "ucast" : 0 }

我真正想要的是

{ "_id" : 28, "ucast" : 676.297664 }

2 个答案:

答案 0 :(得分:0)

您没有记录在这样的聚合管道中获取数组的第一个元素。您希望$arrayElemAt按索引返回数组值:

<matplotlib.figure.Figure at 0x1f75d4750>

如果您的MongoDB不支持$arrayElemAt(3.2之前),那么您可以在文档密钥的附加$first中使用$group,在“累积”之前完成对于所需的分组键:

db.channels.aggregate( [
  { $match: {"channelName": "ABC"} },
  { $unwind : "$rtData" },
  { $group : {
    _id: { $hour: "$rtData.ts" }, 
    ucast: { $sum: { $arrayElemAt: [ "$rtData.data", 0 ] } }
  }}
])

在现代版本中,你可以“双桶”$sum来添加数组元素以及充当累加器,如果你想“求和”数组的所有元素:

db.channels.aggregate( [
  { $match: {"channelName": "ABC"} },
  { $unwind : "$rtData" },
  { $group: { 
    _id: { _id: "$_id", ts: "$rtData.ts" },
    data: { $first: "$rtData.data" }
  }},
  { $group : {
    _id: { $hour: "$_id.ts" }, 
    ucast: { $sum: "$data" }
  }}
])

对于旧版本(3.2之前的版本),你会为每个数组路径“加倍”$unwind

db.channels.aggregate( [
  { $match: {"channelName": "ABC"} },
  { $unwind : "$rtData" },
  { $group : {
    _id: { $hour: "$rtData.ts" }, 
    ucast: { $sum: { $sum: "$rtData.data" } }
  }}
])

答案 1 :(得分:0)

你需要使用$ first运算符代替$ sum

db.channels.aggregate( [ {$match: {"channelName": "ABC"} }, { $unwind : "$rtData" }, { $group : {_id: { $hour: "$rtData.ts" }, ucast: { $first: $rtData.data} }

将为您提供类似{&#34; _id&#34; :28,&#34; ucast&#34; :[676.297664,676.297664]}

如果你想输出{&#34; _id&#34; :28,&#34; ucast&#34; :676.297664}在下一个$ project或$ addFields阶段使用$ arrayElemAt