如何在MongoDB中聚合时间序列数据
我有MongoDB文档,就像这里解释的一样 因此,每天有一个文档(以及类型和系统),其中有一个如何在MongoDB中聚合时间序列数据,mongodb,time-series,aggregation-framework,Mongodb,Time Series,Aggregation Framework,我有MongoDB文档,就像这里解释的一样 因此,每天有一个文档(以及类型和系统),其中有一个values字段,其中包含小时、分钟和秒数据,如下所示: { "_id" : ObjectId("59fc57d75bc7315366b78799"), "date" : ISODate("2017-11-03T00:00:00.000+0000"), "system" : "192-168-1-30", "type" : "memory", "valu
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
有什么提示吗?您缺少这篇文章的要点,它基本上描述了一个具有预聚合数据的系统: “num_samples”和“total_samples”字段会随着新读数应用于文档而更新: 因此,每个文档都包含每个文档的值数和值总数。因此,如果您将这两个字段添加到文档中,您可以通过将总值除以数字值来轻松计算每日平均值 这篇文章很旧。一方面,Mongodb从那时起有了很大的发展,另一方面,上面提到的项目被放弃了。我特别为方形立方体一号的命运感到遗憾 从v3.4开始,您可以从中受益,以实现以下运行时分组:
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
}
在此之后,您可以按秒、分、小时将聚合阶段应用于分组
问题是它非常昂贵,而且小时、分钟和秒都是字符串,这只会使操作更加复杂
首先,每秒存储一个文档要简单得多。是每60秒、1小时等存储一个文档,还是最后60秒、1小时等存储一个文档?嗯,这是什么意思?我几乎每秒都会得到数据,我希望它平均按分钟、小时等进行聚合。哦,我看到了你们所说的部分。“For each”,更新…非常感谢,所以您认为使用大量文档而不是这种(旧的)方法更有效率吗?我知道每秒保存1个文档会越来越容易,但我想我会收集大量的记录(我必须监控10k系统)。@Michelem你的后续问题一针见血。对于数据量不允许在运行时聚合数据的系统,预聚合数据是一种利基方法。如果每秒有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
}