我的模式实施受到本教程on official mongo site
的影响{
_id: String,
data:[
{
point_1: Number,
ts: Date
}
]
}
这基本上是为时间序列数据设计的架构,我将每个设备每小时的数据存储在一个文档中的数组中。我创建了_id
字段,该字段结合了发送数据和时间的设备ID。例如,如果具有ID xyz1234
的设备在2018-09-11 12:30:00
发送数据,则我的_id
字段将变为xyz1234:2018091112
。
如果该设备该小时的文档不存在,我将创建新文档,否则我将数据推送到data
数组中。
client.db('iot')
.collection('iotdata')
.update({_id:id},{$push:{data:{point_1,ts:date}}},{upsert:true});
现在我在进行聚合时遇到问题。我正在尝试获取这些类型的值
point_1
值point_1
值
point_1
我认为这是一个非常简单的聚合,然后我意识到设备ID不是直接的,而是与时间数据混合在一起的,因此按设备ID分组数据并不是那么直接。如何根据设备ID划分_id和组?我尽力使自己的问题尽可能清楚地写出来,所以如果问题的任何部分不清楚,请在评论中提出问题。
答案 0 :(得分:1)
您可以从$unwind开始处理数据,以获取每个条目一个文档。然后,您可以使用$substr和$indexOfBytes运算符来获得deviceId
。然后,您可以应用过滤条件(过去24
小时),然后使用$group
获取min
,max
和avg
db.col.aggregate([
{
$unwind: "$data"
},
{
$project: {
point_1: "$data.point_1",
deviceId: { $substr: [ "$_id", 0, { $indexOfBytes: [ "$_id", ":" ] } ] },
dateTime: "$data.ts"
}
},
{
$match: {
dateTime: { $gte: ISODate("2018-09-10T12:00:00Z") }
}
},
{
$group: {
_id: "$deviceId",
min: { $min: "$point_1" },
max: { $max: "$point_1" },
avg: { $avg: "$point_1" }
}
}
])
答案 1 :(得分:1)
您可以在3.6中使用以下查询。
db.colname.aggregate([
{"$project":{
"deviceandtime":{"$split":["$_id", ":"]},
"minpoint":{"$min":"$data.point_1"},
"maxpoint":{"$min":"$data.point_1"},
"sumpoint":{"$sum":"$data.point_1"},
"count":{"$size":"$data.point_1"}
}},
{"$match":{"$expr":{"$gte":[{"$arrayElemAt":["$deviceandtime",1]},"2018-09-10 00:00:00"]}}},
{"$group":{
"_id":{"$arrayElemAt":["$deviceandtime",0]},
"minpoint":{"$min":"$minpoint"},
"maxpoint":{"$max":"$maxpoint"},
"sumpoint":{"$sum":"$sumpoint"},
"countpoint":{"$sum":"$count"}
}},
{"$project":{
"minpoint":1,
"maxpoint":1,
"avgpoint":{"$divide":["$sumpoint","$countpoint"]}
}}
])