我有MongoDB文档,如https://www.mongodb.com/blog/post/schema-design-for-time-series-data-in-mongodb
所述每天(和类型和系统)的1个文档,其中values
字段包含小时,分钟和秒数据,所以这样:
{
"_id" : ObjectId("59fc57d75bc7315366b78799"),
"date" : ISODate("2017-11-03T00:00:00.000+0000"),
"system" : "192-168-1-30",
"type" : "memory",
"values" : {
[...]
"11" : { // hour 11
[...]
"49" : { // minute 49
[...]
"43" : NumberInt(62171000), // second 43
"44" : NumberInt(62169000),
[...]
},
"50" : {
"1" : NumberInt(62363000),
"2" : NumberInt(62319000)
[...]
},
[...]
},
[...]
},
"updatedAt" : ISODate("2017-11-03T13:34:00.720+0000"),
"createdAt" : ISODate("2017-11-03T11:49:43.442+0000")
}
例如,在2017-11-03的11:49:43,记忆是在62171000。
现在我正在尝试获取这些文档的聚合数据,以获取每分钟,小时等平均数据的行,但我很困惑如何告诉聚合框架$ values是一个小时数组,分钟和秒钟。
或者我应该使用map / reduce?
任何提示?
答案 0 :(得分:3)
您缺少本文的基本要点,它基本上描述了具有预聚合数据的系统:
当新的读数应用于文档时,字段“num_samples”和“total_samples”会更新:
{$set: {“values.59”: 2000000 }},
{$inc: {num_samples: 1, total_samples: 2000000 }}
这样每个文档都包含多个值和每个文档的总值。因此,如果您将这两个字段添加到文档中,则可以通过将total_values除以number_values轻松计算每日平均值。
这篇文章很老了。从那时起Mongodb从一方面显着发展,从另一方面提到那里的项目被抛弃了。我特别感谢Square Cube的命运。
从v3.4开始,您可以从objectToArray中受益,以实现运行时分组,如下所示:
db.collection.aggregate([
{$project:{
date : 1, system : 1, type : 1,
hour: {$objectToArray: "$values" }
}},
{$unwind: "$hour"},
{$project:{
date : 1, system : 1, type : 1,
hour: "$hour.k",
minute: {$objectToArray: "$hour.v" }
}},
{$unwind: "$minute"},
{$project:{
date : 1, system : 1, type : 1, hour: 1,
minute: "$minute.k",
second: {$objectToArray: "$minute.v" }
}},
{$unwind: "$second"},
{$project:{
date : 1, system : 1, type : 1, hour: 1, minute: 1,
second: "$second.k",
value: "$second.v"
}},
])
以下列格式每秒为您提供1个文档:
{
"_id" : ObjectId("59fc57d75bc7315366b78799"),
"date" : ISODate("2017-11-03T00:00:00.000Z"),
"system" : "192-168-1-30",
"type" : "memory",
"hour" : "11",
"minute" : "49",
"second" : "43",
"value" : 62171000
}
您可以在此之后应用聚合阶段,按秒,分钟,小时进行分组。
问题是它非常昂贵,而且小时,分钟和秒都是字符串,这只会使操作变得更加复杂。
首先,每秒存储1个文档会更简单。