我正在尝试在mongo中使用map-reduce,并且遇到了一个让我完全难倒的数值问题。给定以下map和reduce函数:
var map = function(){
key = "awesome";
emit(key, {count: 1})
}
var reduce = function(key, values){
var result = {count: 0};
values.forEach(function(value) {
result.count += value.count;
});
result.countBy2 = result.count/2
// result.count = result.count/2
return result
}
给出逻辑
"results" : [
{
"_id" : "awesome",
"value" : {
"value" : {
"count" : 7696.0000000000000000,
"countBy2" : 3848.0000000000000000
}
},
顶部代码片段中的取消注释行给出了非常奇怪的输出
"results" : [
{
"_id" : "awesome",
"value" : {
"count" : 98.0000000000000000,
"countBy2" : 98.0000000000000000
}
},
为什么?
反转注释行,以保持map和reduce命令的对象格式相同(关联?)。
// result.countBy2 = result.count/2
result.count = result.count/2
仍然输出意外
"results" : [
{
"_id" : "awesome",
"value" : {
"count" : 98.0000000000000000
}
}
我错过了什么?
当您的reduce
函数包含将count
除以2的线时,它违反了文档中描述的对reduce函数必须坚持的幂等要求:
减小函数必须是幂等的。确保以下语句为真:
reduce( key, [ reduce(key, valuesArray) ] ) == reduce( key, valuesArray )
这基本上表示您需要能够将一个reduce
调用的输出作为输入返回到另一个调用,并使结果保持不变。
如果你想对map-reduce的输出执行最终处理,那么你可以在选项中包含一个只会被调用一次的finalize函数。根据你最终想要做的事情,这可能是你应该将计数除以2的地方:
finalize: function(key, reducedValue) { return { count: reducedValue.count/2 }; }