日期范围内按天计算的MongoDB集合中的事件计数

时间:2014-06-03 22:00:17

标签: mongodb mapreduce aggregation-framework

我试图弄清楚如何在指定日期范围内的所有日期执行MongoDB集合中的事件计数。

MongoDB中的示例文档架构:

{
    eventNum: 1234,
    startDate:ISODate("2014-01-01"),
    endDate: ISODate("2014-01-04")
    eventType: System Crash
}
{
    eventNum: 4567,
    startDate: ISODate("2014-01-04"),
    endDate: ISODate("2014-01-05")
    eventType: Maintenance
}

我想要的是日期范围:

1/1/2014 - 1/6/2014

此范围内每天的总计数事件是多少?

结果将是:

1/1/2014: 1
1/2/2014: 1
1/3/2014: 1
1/4/2014: 2
1/5/2014: 1
1/6/2014: 0

我的问题实际上在于被跟踪的数据不是基于个人日的事实,这将允许我按日期执行基本聚合。事件有开始和结束日期。

1 个答案:

答案 0 :(得分:2)

不幸的是,更多mapReduce问题,否则您无法发出使其工作所需的日期。

db.events.mapReduce(
    function() {
        var oneDay = ( 1000 * 60 * 60 * 24 ),
            start = this.startDate.valueOf()
            - ( this.startDate.valueOf() % oneDay ),
            end = ((this.endDate.valueOf()
            - ( this.endDate.valueOf() % oneDay )) + oneDay);

        for ( var day = start; day < end; day += oneDay ) {
           emit ( new Date( day ), 1 );
        }
    },
    function(key, values) {
        return Array.sum( values );
    },
    { 
         "query": { 
             "startDate": { "$gte": new Date("2014-01-01") },
             "endDate": { "$lt": new Date("2014-01-06") }
          },
         "out": { "inline": 1 }
    }
)

如果你真的想要在日期范围内不存在的事件的零值,你可以改变一点:

db.events.mapReduce(
    function() {
        var oneDay = ( 1000 * 60 * 60 * 24 ),
            start = this.startDate.valueOf()
            - ( this.startDate.valueOf() % oneDay ),
            end = ((this.endDate.valueOf()
            - ( this.endDate.valueOf() % oneDay )) + oneDay);

        for ( var day = start; day < end; day += oneDay ) {
           emit ( new Date( day ), 1 );
        }

        for ( var day = end; day <= ending.valueOf(); day += oneDay ) {
           emit( new Date( day ), 0 );
        }

    },
    function(key, values) {
        return Array.sum( values );
    },
    { 
         "query": { 
             "startDate": { "$gte": new Date("2014-01-01") },
             "endDate": { "$lt": new Date("2014-01-06") }
          },
          "scope": { "ending": new Date("2014-01-06") },
          "out": { "inline": 1 }
    }
)

它为您提供所需的输出:

   "results" : [
            {
                    "_id" : ISODate("2014-01-01T00:00:00Z"),
                    "value" : 1
            },
            {
                    "_id" : ISODate("2014-01-02T00:00:00Z"),
                    "value" : 1
            },
            {
                    "_id" : ISODate("2014-01-03T00:00:00Z"),
                    "value" : 1
            },
            {
                    "_id" : ISODate("2014-01-04T00:00:00Z"),
                    "value" : 2
            },
            {
                    "_id" : ISODate("2014-01-05T00:00:00Z"),
                    "value" : 1
            },
            {
                    "_id" : ISODate("2014-01-06T00:00:00Z"),
                    "value" : 0
            }
]