2014-01-24 133 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