2015-07-21 114 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

太棒了,看起來它會做的。 –