MongoDB、时间序列和聚合框架
Posted
技术标签:
【中文标题】MongoDB、时间序列和聚合框架【英文标题】:MongoDB, TimeSeries and Aggregation Framework 【发布时间】:2015-10-24 20:54:39 【问题描述】:所以,我正在使用 MongoDB 处理这个时间序列数据并发现: http://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in-mongodb
它说这种结构不会利用“文档模型的表达性”:
timestamp: ISODate("2013-10-10T23:06:37.000Z"),
type: ”memory_used”,
value: 1000000
他们建议像这样(分钟/秒):
timestamp_hour: ISODate("2013-10-10T23:00:00.000Z"),
type: “memory_used”,
values:
0: 0: 999999, 1: 999999, …, 59: 1000000 ,
1: 0: 2000000, 1: 2000000, …, 59: 1000000 ,
…,
所以我决定像这样(年/月)对我的数据进行建模:
"unity_of_measure": "MWh",
"region": "North",
"consumption":
2014: 1: 2568.652, 2: 2614.621, 3: 2711.012 ,
2015: 1: 2751.234, 2: 2752.231, 3: 2752.215 ,
…
我不知道我是不是搞错了,但是聚合框架似乎无法获得最大/最小/总和/平均值,例如,使用这种建模。
所以我把我的模型改成了这样:
"unity_of_measure": "MWh",
"region": "North",
"consumption": [
"year": 2014,
"month": 1,
"value": 2568.652
,
"year": 2014,
"month": 2,
"value": 2614.621
...
]
但现在我发现自己没有利用“文档模型的表达性”。所以我真的很困惑。
有没有什么方法可以使用聚合框架和 mongo 的博客建议的建模?这里的想法是不使用 map reduce 或类似的东西。
如果不可能,第二次建模在性能方面有多糟糕?
抱歉这个问题太长了,我希望我能在这里贴一个土豆。
提前致谢。
【问题讨论】:
不要太拘泥于“文档模型的表达性”——我认为这是文章中的不幸措辞。他们提出的模式只是一种有助于满足设计目标的选择。它因其他设计目标而失败,如下所述。六年前,我在 Oracle 中编写了完全相同的策略,而 mongo 设计不再具有表现力——它们在功能上是等效的,并且具有相似的表现力。 你好史蒂夫塔弗。非常感谢您与我和社区分享的所有信息和经验,它确实帮助我考虑了很多事情!如果你知道一些文章或任何讨论这个话题的东西,你能和我分享吗?再次感谢! 哪个主题?大规模指标收集或列表计算? 【参考方案1】:我认为您错过了文章中的一些重要内容 -> 他们会在每次更新时更新汇总统计字段,以便他们可以计算应用程序中的平均值。他们在时间序列数据上使用 $set,在 num_samples 和 total_samples 上使用 $inc,因为文档字段更新非常便宜并且允许它们达到它们所处的规模。时间序列数据用于显示 - 不用于 mongo 中的计算。
聚合和映射函数对列表进行操作 - 您的第一个示例没有 - 它有一个包含时间序列数据的子文档。您可以在聚合管道中进行平均,但在应用程序代码中这样做会非常难看且更简单。
如果您想在 mongo 中进行计算,则必须将数据组织在某种列表中,例如您的第二个示例。
使用第二个模式作为提示,您可以按照以下方式进行计算。打开一个 mongo shell,使用一个像 test 一样的临时数据库,然后将其粘贴进去看看它是否工作。
// clean up from previous run
db.timeSeries2.drop();
// Given data like
db.timeSeries2.insert(
"unit_of_measure": "MWh",
"region": "North",
"consumption": [
"year": 2014,
"month": 1,
"value": 50
,
"year": 2014,
"month": 2,
"value": 100
,
"year": 2014,
"month": 3,
"value": 150
,
"year": 2015,
"month": 1,
"value": 500
,
"year": 2015,
"month": 2,
"value": 1000
,
"year": 2015,
"month": 3,
"value": 1500
]
);
// aggregation to provide min/max/sum/average
db.timeSeries2.aggregate([
$match: region: 'North', unit_of_measure: 'MWh',
$unwind: '$consumption',
$match: 'consumption.year': 2014,
$group:
_id: 'summary',
avg: $avg: '$consumption.value',
sum: $sum: '$consumption.value',
min: $min: '$consumption.value',
max: $max: '$consumption.value'
])
生产
"result": [
"_id": "summary",
"avg": 100,
"sum": 300,
"min": 50,
"max": 150
],
"ok": 1
【讨论】:
以上是关于MongoDB、时间序列和聚合框架的主要内容,如果未能解决你的问题,请参考以下文章