MongoDB 时间序列聚合
MongoDB Time Series Aggregation
我正在以可配置的时间间隔读取传感器数据,但对于此示例,假设每 30 秒一次。我希望能够按小时、天、周、月和年间隔对数据进行分组。我还希望能够在相同的时间间隔内聚合一组传感器的平均值。
示例用例:
1.获取传感器 ID 最近 4 个月的总数:x
2。获取具有 group_id 的传感器最近 4 个月的平均总数:y
已阐明用例 2
以下都一样group_id
sensor_id | month 1 | month 2 | month 3 | month 4
1 | 10 | 15 | 5 | 10
2 | 20 | 30 | 30 | 5
3 | 5 | 20 | 40 | 20
输出
month1 : 11.67, month2: 21.67, month3: 25, month4: 11.67
我见过很多在 MongoDB 中存储时间序列数据的方法。我正在考虑为每个时间间隔收集一个集合,包括原始时间值并让每个文档在特定时间段后过期。
MonthPoint 示例文档
{
"_id": {
"$oid": "55270059a791051d4a4e0e41"
},
"sensor_id": "1",
"group_id" : "4",
"timestamp": {
"$date": "2015-04-01T00:00:00.000Z"
},
"sum": 40
"count": 200
}
对于进入的每个点,我都必须对每个集合执行写入操作,但读取数据会很快。
用例 1,将是一个非常简单的查询:
MonthPoints.find({
sensor_id : x,
timestamp : {
$gte: startDate,
$lt: currentDate
}
});
但是我将如何为用例 2 聚合?是否有可能在一次聚合中实现这一目标?我看到了如何使用 4 个单独的聚合来实现它,在 group_id.
中获取每个月的平均值
我有以下合集:
> db.mpoints.find()
{ "_id" : ObjectId("55ae6d35931d911f97d09977"), "g" : 55, "s" : 1, "v" : 10, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d3d931d911f97d09978"), "g" : 55, "s" : 2, "v" : 20, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d42931d911f97d09979"), "g" : 55, "s" : 3, "v" : 5, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d49931d911f97d0997a"), "g" : 11, "s" : 3, "v" : 5, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d54931d911f97d0997b"), "g" : 55, "s" : 3, "v" : 20, "d" : ISODate("2015-04-30T00:00:00Z") }
{ "_id" : ObjectId("55ae6d8a931d911f97d0997c"), "g" : 55, "s" : 2, "v" : 20, "d" : ISODate("2015-04-30T00:00:00Z") }
{ "_id" : ObjectId("55ae6dc2fc560cbbe2b22400"), "g" : 55, "s" : 1, "v" : 50, "d" : ISODate("2015-04-30T00:00:00Z") }
字段的映射是:
d
- 是日期 - 我将其作为该月的最后一天。您也可以将其作为本月的第一天。没关系。
g
- 你的组号
s
- 您的传感器 ID
v
- 你的价值
聚合调用为
db.mpoints.aggregate([
{
$match: {
"g": 55,
"d": {
"$gte": ISODate("2015-03-31T00:00:00Z"),
"$lte": ISODate("2015-04-30T00:00:00Z")
}
}
},
{
$group: {
"_id": "$d",
total: {
$sum: '$v'
},
count: {
$sum: 1
}
}
}
])
结果是
{ "_id" : ISODate("2015-04-30T00:00:00Z"), "total" : 90, "count" : 3 }
{ "_id" : ISODate("2015-03-31T00:00:00Z"), "total" : 35, "count" : 3 }
您将获得每个月的总数和该月的条目数。
我正在以可配置的时间间隔读取传感器数据,但对于此示例,假设每 30 秒一次。我希望能够按小时、天、周、月和年间隔对数据进行分组。我还希望能够在相同的时间间隔内聚合一组传感器的平均值。
示例用例:
1.获取传感器 ID 最近 4 个月的总数:x
2。获取具有 group_id 的传感器最近 4 个月的平均总数:y
已阐明用例 2
以下都一样group_id
sensor_id | month 1 | month 2 | month 3 | month 4
1 | 10 | 15 | 5 | 10
2 | 20 | 30 | 30 | 5
3 | 5 | 20 | 40 | 20
输出
month1 : 11.67, month2: 21.67, month3: 25, month4: 11.67
我见过很多在 MongoDB 中存储时间序列数据的方法。我正在考虑为每个时间间隔收集一个集合,包括原始时间值并让每个文档在特定时间段后过期。
MonthPoint 示例文档
{
"_id": {
"$oid": "55270059a791051d4a4e0e41"
},
"sensor_id": "1",
"group_id" : "4",
"timestamp": {
"$date": "2015-04-01T00:00:00.000Z"
},
"sum": 40
"count": 200
}
对于进入的每个点,我都必须对每个集合执行写入操作,但读取数据会很快。
用例 1,将是一个非常简单的查询:
MonthPoints.find({
sensor_id : x,
timestamp : {
$gte: startDate,
$lt: currentDate
}
});
但是我将如何为用例 2 聚合?是否有可能在一次聚合中实现这一目标?我看到了如何使用 4 个单独的聚合来实现它,在 group_id.
中获取每个月的平均值我有以下合集:
> db.mpoints.find()
{ "_id" : ObjectId("55ae6d35931d911f97d09977"), "g" : 55, "s" : 1, "v" : 10, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d3d931d911f97d09978"), "g" : 55, "s" : 2, "v" : 20, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d42931d911f97d09979"), "g" : 55, "s" : 3, "v" : 5, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d49931d911f97d0997a"), "g" : 11, "s" : 3, "v" : 5, "d" : ISODate("2015-03-31T00:00:00Z") }
{ "_id" : ObjectId("55ae6d54931d911f97d0997b"), "g" : 55, "s" : 3, "v" : 20, "d" : ISODate("2015-04-30T00:00:00Z") }
{ "_id" : ObjectId("55ae6d8a931d911f97d0997c"), "g" : 55, "s" : 2, "v" : 20, "d" : ISODate("2015-04-30T00:00:00Z") }
{ "_id" : ObjectId("55ae6dc2fc560cbbe2b22400"), "g" : 55, "s" : 1, "v" : 50, "d" : ISODate("2015-04-30T00:00:00Z") }
字段的映射是:
d
- 是日期 - 我将其作为该月的最后一天。您也可以将其作为本月的第一天。没关系。g
- 你的组号s
- 您的传感器 IDv
- 你的价值
聚合调用为
db.mpoints.aggregate([
{
$match: {
"g": 55,
"d": {
"$gte": ISODate("2015-03-31T00:00:00Z"),
"$lte": ISODate("2015-04-30T00:00:00Z")
}
}
},
{
$group: {
"_id": "$d",
total: {
$sum: '$v'
},
count: {
$sum: 1
}
}
}
])
结果是
{ "_id" : ISODate("2015-04-30T00:00:00Z"), "total" : 90, "count" : 3 }
{ "_id" : ISODate("2015-03-31T00:00:00Z"), "total" : 35, "count" : 3 }
您将获得每个月的总数和该月的条目数。