2017-08-29 38 views
1

我都存储在以下时间序列数据在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 } 

回答

0

你不会得到谱写第一像这样的聚合管道中的数组元素。你想$arrayElemAt其通过索引返回数组值:

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

如果您的MongoDB不支持$arrayElemAt(早于3.2),那么你可以改用$first在附加$group上只是文档键,你以前做过“积累”为需要的分组键:

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" } 
    }} 
]) 

在现代版本中,你可以“双桶”的$sum两者加起来数组元素以及充当蓄能器,如果你想“和” 所有 eleme数组的NTS:与旧版本(3.2之前)

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

,你会“双规” $unwind为每个阵列路径,而不是:

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

感谢您的使用。 – Neeraj

+0

@Neeraj欢迎来到StackOverflow。不要只留下评论说谢谢,而是通过[Accepting the Answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)指出正确答案是一个明确的迹象。 –

0

你需要使用$第一家运营商为代替的$总结

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

,这将给你喜欢输出{ “_id”:28, “尤卡斯特”:676.297664,676.297664]}

如果您希望在下一个$ project或$ addFields阶段使用{“_id”:28,“ucast”:676.297664}输出使用$ arrayElemAt