Mongo将ISODate聚合成45分钟的块

时间:2014-10-16 19:02:08

标签: mongodb

我有一系列具有ISODate对象的文档。我试图把它们分成45分钟的块。所以分钟0-45将是一组,分钟45-下一分钟30将是另一组。

我的第一个想法是划分时间,但由于这些不是unix时间戳,我无法使用ISODate进行数学计算。我的第二个想法是$计划出小时,分钟,天等等,但意识到当时间块跨越两个不同的日子时分组会很困难。

# This doesn't work since you cant do the division.
query = [
    { 
        "$match": {
            '_id.t': { 
                '$gte': new Date(2014, 1, 1, 1, 0, 0),
                '$lte': new Date(2014, 6, 1, 1, 0, 0) 
            }
        }
    },

    {
        "$project": {
            "milliseconds": { '$millisecond': '$_id.t' }
        }
    },

    {

        "$project": {
            "timeblock": { 
                "$divide": [
                    '$milliseconds', 900000
                ]
            }
        }
    },

    {
        "$group": { "_id": { "timeblock": "$timeblock" } }
    }
] 

1 个答案:

答案 0 :(得分:7)

我认为以下可以解决问题:

var baseDate = new Date(2014, 09, 17, 14, 25, 0);  // any value as you want
var startDate = new Date(2014, 09, 17, 14, 25, 0);
var endDate = new Date(2014, 09, 20, 14, 25, 0);
var divisor = 45 * 60 * 1000; // milliseconds of 45 minutes

db.cc.aggregate([ {
    $match : {
        date : {
            $gte : startDate,
            $lt : endDate
        }
    }
}, {
    $group : {
        _id : {
            $subtract : [ "$date", {
                $mod : [ {
                    $subtract : [ "$date", baseDate ]
                }, divisor ]
            } ]
        },
        dates : {
            $push : "$date"
        }
    }
} ]).pretty();

分组说明:

_id : {
    $subtract : [ "$date", {                    /* start date of each block */
        $mod : [ {                              /* remainder */
            $subtract : [ "$date", baseDate ]   /* offset */
        }, divisor ]
    } ]
},