MongoDB时间序列聚合

时间:2015-07-21 15:09:59

标签: mongodb time-series

我正在以可配置的间隔读取传感器数据,但是对于这个例子,我们说每隔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中每个月的平均值。

1 个答案:

答案 0 :(得分:1)

我有以下系列:

> 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 - 您的群组ID
  • 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 }

您可获得每月的总数和该月的参赛人数。

相关问题