MongoDB,时间序列和聚合框架
MongoDB, TimeSeries and Aggregation Framework
所以,我正在使用 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
}
他们提出了这样的建议 (minutes/second):
{
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 },
…,
}
}
所以我决定像这样对我的数据建模,(year/month):
{
"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 } ,
…
}
}
我不知道我是否弄错了,但聚合框架似乎无法获得 max/min/sum/avg 值,例如,使用这种建模。
所以我把模型改成这样:
{
"unity_of_measure": "MWh",
"region": "North",
"consumption": [
{ "year": 2014,
"month": 1,
"value": 2568.652
},
{ "year": 2014,
"month": 2,
"value": 2614.621
}
...
]
}
但现在我发现自己没有利用“文档模型的表现力”。所以我真的很困惑。
有什么方法可以将聚合框架与 mongo 的博客建议的建模一起使用吗?这里的想法不是使用 map reduce 或类似的东西。
如果不可能,那么第二个建模在性能方面有多糟糕?
抱歉这个问题太长了,我希望我能post这里有一个土豆。
提前致谢。
我认为您错过了文章中的一些重要内容 -> 他们会在每次更新时更新汇总统计字段,以便他们可以计算应用程序中的平均值。他们在时间序列数据上使用 $set,在 num_samples 和 total_samples 上使用 $inc,因为文档字段更新非常便宜并且允许它们达到它们所处的规模。时间序列数据用于显示 - 不用于 mongo.
中的计算
聚合和映射函数对列表进行操作 - 您的第一个示例有 none - 它有一个包含时间序列数据的子文档。您 可以 在聚合管道中取平均值,但在应用程序代码中这样做会非常难看且更简单。
如果您想在 mongo 中进行计算,您必须将数据组织在某种列表中,例如您的第二个示例。
使用第二个模式作为提示,下面是您如何进行计算。打开一个 mongo shell,使用类似测试的临时数据库,并将其粘贴进去以查看它是否有效。
// 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 处理这个时间序列数据并发现: 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
}
他们提出了这样的建议 (minutes/second):
{
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 },
…,
}
}
所以我决定像这样对我的数据建模,(year/month):
{
"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 } ,
…
}
}
我不知道我是否弄错了,但聚合框架似乎无法获得 max/min/sum/avg 值,例如,使用这种建模。
所以我把模型改成这样:
{
"unity_of_measure": "MWh",
"region": "North",
"consumption": [
{ "year": 2014,
"month": 1,
"value": 2568.652
},
{ "year": 2014,
"month": 2,
"value": 2614.621
}
...
]
}
但现在我发现自己没有利用“文档模型的表现力”。所以我真的很困惑。
有什么方法可以将聚合框架与 mongo 的博客建议的建模一起使用吗?这里的想法不是使用 map reduce 或类似的东西。
如果不可能,那么第二个建模在性能方面有多糟糕?
抱歉这个问题太长了,我希望我能post这里有一个土豆。
提前致谢。
我认为您错过了文章中的一些重要内容 -> 他们会在每次更新时更新汇总统计字段,以便他们可以计算应用程序中的平均值。他们在时间序列数据上使用 $set,在 num_samples 和 total_samples 上使用 $inc,因为文档字段更新非常便宜并且允许它们达到它们所处的规模。时间序列数据用于显示 - 不用于 mongo.
中的计算聚合和映射函数对列表进行操作 - 您的第一个示例有 none - 它有一个包含时间序列数据的子文档。您 可以 在聚合管道中取平均值,但在应用程序代码中这样做会非常难看且更简单。
如果您想在 mongo 中进行计算,您必须将数据组织在某种列表中,例如您的第二个示例。
使用第二个模式作为提示,下面是您如何进行计算。打开一个 mongo shell,使用类似测试的临时数据库,并将其粘贴进去以查看它是否有效。
// 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
}