2015-07-21 112 views
2

我正在以可配置的时间间隔读取传感器数据,但对于此示例,我们说每30秒。我希望能够按小时,星期,星期,月和年的时间间隔对数据进行分组。我也希望能够以相同的时间间隔在一组传感器上聚合平均值。MongoDB时间序列聚合

示例使用案例:

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获取每个月的平均值。

+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 } 

您可以获得每个月的总数和该月的条目数。

+0

我已更新我的问题以澄清用例2. –

+0

更新了我的答案。检查这是否会工作。 – Sundar

+0

太棒了,看起来它会做的。 –