在mongodb中,我有一个map功能如下:
var map = function() {
emit( this.username, {count: 1, otherdata:otherdata} );
}
Run Code Online (Sandbox Code Playgroud)
并减少功能如下:
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
}
Run Code Online (Sandbox Code Playgroud)
问题在于注意到:
total += value.count;
Run Code Online (Sandbox Code Playgroud)
在我的数据集中,reduce函数被调用9次,并且假设的map减少的结果计数应该是8908.
使用上面的行,返回的结果将正确返回为8908.
但是,如果我将线路更改为:
total += 1;
Run Code Online (Sandbox Code Playgroud)
返回的结果只有909,约为假定结果的1/9.
另外,我尝试了print(value.count),打印结果为1.
什么解释了这种行为?
简短回答:value.count并不总是等于一.
长答案:这是map reduce的预期行为:reduce函数是聚合map函数的结果.但是,它确实通过产生中间结果的小组聚合地图函数的结果(在您的情况下为子总计).然后在这些中间结果上再次运行reduce函数,因为它们是map函数的直接结果.依此类推,直到每个键只剩下一个中间结果,这就是最终结果.
它可以看作是中间结果的金字塔:
emit(...)-|
|- reduce -> |
emit(...)-| |
| |- reduce ->|
emit(...)-| | |
| | |
emit(...)-|- reduce -> | |
| |-> reduce = final result
emit(...)-| |
|
emit(...)--- reduce ------------ >|
|
emit(...)-----------------reduce ->|
减少的数量和它们的输入是不可预测的,并且意味着保持隐藏.这就是为什么你必须提供一个reduce函数,它返回与输入相同类型(相同模式)的数据.
| 归档时间: |
|
| 查看次数: |
1313 次 |
| 最近记录: |