按unix时间戳范围分组

时间:2015-02-20 11:18:17

标签: mongodb mapreduce

我正在尝试从MongoDB集合中每分钟对表进行分组。

我有一个集合,我每秒或多或少有一个文档。使用以下原型:

{
    _id: ...
    type: "value",
    time: 1424421975,
    data: number
}

现在我想创建一个具有相同原型的第二个集合,该集合首先按类型分组,然后按时间(每分钟)分组。

我已经尝试过使用MongoDB中的map reduce的一些东西,但是我无法使其工作。

var mapFunction1 = function() {
    var firstTimestamp = db.collection.find({type: this.type}).sort({time: 1}).limit(1)[0].time;

    var keyValue = Math.floor((this.time - firstTimestamp) / 60) * 60 + firstTimestamp;

    emit(this.type + '_' + keyValue, this);
}

var reduceFunction1 = function(key, value) {
    return value;
};

db.loadServerScripts();
db.runCommand({
    mapreduce: "collection", 
    map: mapFunction1, 
    reduce: reduceFunction1, 
    out: "map_reduce_example",
    scope: {db: db}
});

给出错误消息:

    {
    "errmsg" : "exception: TypeError: Object db.collection has no method 'find' near 'collection.find({type:this.type'  (line 2)",
    "code" : 16722,
    "ok" : 0
}

1 个答案:

答案 0 :(得分:2)

您可以使用聚合管道。诀窍是使用arithmetic operators计算分钟数:

db.collection.aggregate([
    { "$group" :  { 
        "_id" : { 
            "type" : "$type", 
            "minute" : {
                "$divide" : [
                    { "$subtract" : ["$time", { "$mod" : ["$time", 60] }] },
                    60
                ]
            }
        }, 
        "data" : { "$sum" : "$data" }    // assuming you want to add up data for seconds
    } }
])

如果要在分钟数之间调整不同的边界,请在$time表达式中向$subtract添加偏移量。如果您想让自己的生活更轻松(在这种情况下),请将time替换为实际日期类型并使用$minute