1

我在我的 mongodb 数据库中收集了大约 10 个 mio 文档,这些文档跨越几个星期,我希望能够计算一些简单的统计数据并输出它们。我试图获得的统计数据是一个时间跨度内每个文档的平均评分,以一小时为间隔。

要了解我正在尝试做什么,请遵循以下 sudo 代码:

var dateTimeStart;
var dateTimeEnd;

var distinctHoursBetweenDateTimes = getHours(dateTimeStart, dateTimeEnd);

var totalResult=[];

foreach( distinctHour in distinctHoursBetweenDateTimes )
    tmpResult = mapreduce_getAverageRating( distinctHour, distinctHour +1 )
    totalResult[distinctHour] = tmpResult;

return totalResult;

我的文档结构类似于:{_id, rating, topic, created_at}

Created_at 是我收集统计数据的日期(插入时间和创建时间并不总是相同)

我在 created_at 字段上创建了一个索引。

以下是我的mapreduce:

map = function (){ 
    emit( this.Topic , { 'total' : this.Rating , num : 1 } ); 
};

reduce = function (key, values){  
    var n = {'total' : 0, num : 0}; 
    for ( var i=0; i<values.length; i++ ){ 
        n.total += values[i].total; 
        n.num += values[i].num; 
    } 
    return n; 
};

finalize = function(key, res){ 
    res.avg = res.total / res.num; 
    return res; 
};

我很确定这可以更有效地完成 - 可能通过让 mongo 做更多的工作,而不是连续运行几个 map-reduce 语句。

在这一点上,每个 map-reduce 大约需要 20-25 秒,因此几天内所有时间的统计数据突然占用了很长时间。

我的印象是 mongo 应该适合这种工作 - 因此我显然做错了什么。

谢谢你的帮助!

4

1 回答 1

1

我假设时间是您正在 MapReducing 文件的一部分?

当您在所有文档上运行 MapReduce 时,确定 map 函数中的小时并将其添加到您发出的键中,您可以在单个 MapReduce 中完成所有这些操作。

于 2012-11-16T09:46:46.670 回答