2014-01-24 130 views
2

我需要根據一定的時間間隔來聚合我的收藏。如何在MongoDB中按時間間隔聚合文檔?

您可能認爲,我不需要計算例如我們每天每小時。

我需要基於30分鐘的時間間隔(或任何其他)進行聚合。比方說,第一份文件是在下午3點45分創建的。然後還有5個文件,在下午3:45到4:15之間創建。 所以在這段時間內,我有6個文件。因此,MapReduce結果的第一個文檔是一個計數爲6的文檔。

假設下一個文檔是在4:35 PM創建的,而另外三個文檔是在4:40 PM創建的。

所以MapReduce的結果的下一個文件是用4

等等計數的文檔......

目前我的地圖功能看起來像這樣:

var map = function() {          
     var key = {name: this.name, minute: this.timestamp.getMinutes()}; 
     emit(key, {count: 1}) 
}; 

沒什麼特別的。目前我按分鐘分組,這不是我想要的結果。在這裏,而不是一分鐘,我需要能夠檢查上述時間間隔。

而且我減少功能:

var reduce = function(key, values) 
{ 
    var sum = 0; 
    values.forEach(function(value) 
    { 
     sum += value['count']; 
    }); 
    return {count: sum}; 
}; 

的這個輸出是這樣的:

{ 
0: "{ "_id" : { "name" : "A" , "minute" : 11.0} , "value" : { "count" : 1.0}}", 
1: "{ "_id" : { "name" : "B" , "minute" : 41.0} , "value" : { "count" : 6.0}}", 
2: "{ "_id" : { "name" : "B" , "minute" : 42.0} , "value" : { "count" : 3.0}}", 
3: "{ "_id" : { "name" : "C" , "minute" : 41.0} , "value" : { "count" : 2.0}}", 
4: "{ "_id" : { "name" : "C" , "minute" : 42.0} , "value" : { "count" : 2.0}}", 
5: "{ "_id" : { "name" : "D" , "minute" : 11.0} , "value" : { "count" : 1.0}}", 
6: "{ "_id" : { "name" : "E" , "minute" : 16.0} , "value" : { "count" : 1.0}}" 
} 

所以它計數/聚合每分鐘的文件,而不是由我自定義的時間間隔。

這個任何想法?

回答

1

編輯:我使用map reduce的例子不起作用,但我認爲這大致上是你想要做的。 我使用項目來定義一個變量time以包含從時間戳四捨五入到5分鐘間隔的分鐘數。用整數除法很容易,但我不認爲mongodb查詢語言目前支持這種語言,所以我只需從分鐘中減去minutes mod 5即可獲得每5分鐘更改一次的數字。然後由這個名字和這個時間計數器組成的小組應該這樣做。

query = [ 
    { 
     "$project": { 
      "_id":"$_id", 
      "name":"$name", 
      "time": { 
       "$subtract": [ 
        {"$minute":"$timestamp"}, 
        {"$mod": [{"$minute":"$timestamp"}, 5]} 
       ] 
      } 
     } 
    }, 
    { 
     "$group": {"_id": {"name": "$name", "time": "$time"}, "count":{"$sum":1}} 
    } 
] 
db.foo.aggregate(query) 
+0

謝謝,但這是行不通的。可以說,我們用30(Math.floor(timestamp.getMinutes()/ 30)的方法來處理,意味着我們只能按半小時進行分組,因此14:25 PM和14:35 PM的文檔將被計數兩次 – user3169506

+0

I編輯我的評論,我認爲它應該工作,14:25文檔將落入25格30 = 0括號,35分格30 = 1分鐘括號中的14:35分文檔爲了清楚起見,您可以使用'30 * Math.floor(timestamp.getMinutes()/ 30)'當然,根據你的數據集,在小時,天,月,年添加一個因子可能是有意義的,否則14:35和15:35會結束 – Mzzl

+1

你想從一個任意的起點,而不是從一個小時的30分鐘的時間內聚集嗎?所以從14:35到15:05的一段時間? – Mzzl