我试图按照以下描述对我的时间序列数据建模:
http://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in-mongodb
这是一个简化的例子,对一年中每天的每个小时进行两次测量:
{
year: 2042,
id: 42,
dataType: "something",
data :
{
"1" : {
"1" : [240,210],
"2" : [230,220],
"24" : [220,130]
},
"365" : {
"1" : [140,110],
"2" : [130,120],
"24" : [120,130]
}
}
}
通过上面的例子,我喜欢将每小时的第一次测量检索为每小时所有第一个值的单个数组:
[240,230,220,140,130,120]
我曾尝试使用pymongo / python和循环,但这太慢了,显然非常低效。我也试图调查聚合,但没有任何运气。
答案 0 :(得分:1)
1)您可以使用聚合管道通过使用以下内容重建对象:
db.messurements.aggregate([
{$project: {
year : 1,
id : 1,
dataType : 1,
data: [
{ day: { $literal: 1 }, values : "$data.1"},
{ day: { $literal: 365 }, values : "$data.365"}
]}
}
]);
这将产生以下输出:
{
"_id" : ObjectId("58416371cf34fc678d4f161c"),
"year" : 2042,
"id" : 42,
"dataType" : "something",
"data" : [
{
"day" : 1,
"values" : {
"1" : [
240,
210
],
"2" : [
230,
220
],
"24" : [
220,
130
]
}
},
{
"day" : 365,
"values" : {
"1" : [
140,
110
],
"2" : [
130,
120
],
"24" : [
120,
130
]
}
}
]
}
2)它并不漂亮,但以下聚合查询会给出预期的结果:
db.messurements.aggregate([
{$project: {
year : 1,
id : 1,
dataType : 1,
data: [
{ day: { $literal: 1 }, values : "$data.1"},
{ day: { $literal: 365 }, values : "$data.365"}
]}},
{$unwind: "$data"},
{$project: {
year : 1,
id : 1,
dataType : 1,
data: [
{ day: "$data.day", hour: { $literal: 1 }, values : "$data.values.1"},
{ day: "$data.day", hour: { $literal: 2 }, values : "$data.values.2"},
{ day: "$data.day", hour: { $literal: 24 }, values : "$data.values.24"}
]}},
{$unwind: "$data"},
{$project: {
year : 1,
day: "$data.day",
hour: "$data.hour",
id : 1,
dataType : 1,
values: "$data.values"
}},
{$unwind: "$values"},
{$group: {
_id: {
year: "$year",
day :"$day",
hour: "$hour"},
data: {$first: "$values"}
}},
{$group: {
_id: "",
data: { $push : "$data" }
}}
]);
将输出:
{ "_id" : "", "data" : [ 120, 130, 140, 220, 230, 240 ] }
3) 我发现mongodb网站非常适合您使用数据操作所做的事情,请参阅 - https://docs.mongodb.com/v3.2/reference/operator/aggregation/