如何在MongoDB中按时间间隔汇总文档?

时间:2014-01-24 09:41:54

标签: mongodb mapreduce aggregation-framework

我需要根据特定时间间隔汇总我的收藏。

你可能认为,我不需要计算,例如我们每天每小时。

我需要根据30分钟的间隔(或任何其他)进行聚合。可以说,第一份文件是在下午3:45创建的。然后还有5个文档,在下午3:45到4:15之间创建。 所以在这段时间内,我有6个文件。因此,MapReduce结果的第一个文档是一个计数为6的文档。

我们说,下一个文档是在下午4:35创建的,另外三个是在下午4:40创建的。

因此,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 个答案:

答案 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)