MongoDB MapReduce 值计数

3
在mongodb中,我有以下地图函数:
var map = function() {
    emit( this.username, {count: 1, otherdata:otherdata} );
}

并将reduce函数修改如下:

var reduce = function(key, values) { 
    values.forEach(function(value){
        total += value.count; //note this line
    }
    return {count: total, otherdata: values[0].otherdata}; //please ignore otherdata
}

问题出在下面这行代码上:
total += value.count;

在我的数据集中,reduce函数被调用了9次,预计的映射减少结果计数应该为8908。
使用上述行,返回结果将正确地返回为8908。
但是,如果我将该行更改为:
total += 1;

返回的结果只有909,大约是预期结果的1/9。
同时,我尝试了print(value.count),打印出来的结果是1。
这种行为是如何解释的?

你不需要在某个地方声明 total 吗? - Thilo
2个回答

7
简短回答:value.count并不总是等于1。
详细回答:这是map reduce的预期行为:reduce函数聚合map函数的结果。然而,它会按小组对map函数的结果进行聚合生成中间结果(在您的情况下是子总计)。然后,再次运行reduce函数,将这些中间结果视为来自map函数的直接结果。一直重复这个过程,直到每个键只剩下一个中间结果为止,这就是最终结果。
可以将其看作是中间结果的金字塔:
emit(...)- | |- reduce -> | emit(...)-| | | |- reduce ->| emit(...)-| | | | | | emit(...)-|- reduce -> | | | |-> reduce = final result emit(...)-| | | emit(...)--- reduce ------------ >| | emit(...)-----------------reduce ->|
减少数量及其输入是不可预测的,并且意味着必须提供一个返回与输入相同类型(相同模式)数据的reduce函数。

2

reduce函数不仅会被调用原始输入数据,还会被调用其自身的输出,直到得到最终结果。因此,它需要能够处理这些中间结果,例如 [{count: 5}, {count:3}, {count: 4}] ,这是一个早期阶段的输出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接