我正在使用MongoDB,并希望计算集合中每个不同的“concatenated_handles”(带字符串类型的字段)的出现次数。
我还必须根据出现次数进行排序,所以我决定使用mapreduce,这一切都很顺利,但突然间我开始得到意想不到的结果而且我没有改变任何代码
这是我的地图:
function() { emit(this.concatenated_handles, { count: 1}); }
这是减少:
r = function(key, values) { var result = {count : 0}; values.forEach(function(value) { result.count++; }); return result; }
它为某些字段返回正确的值,而对其他字段则不正确。我记录了输出,这里是(仅显示被窃听的字段)
msdhoni#yuvstrong12:0
msdhoni#yuvstrong12:1
msdhoni#yuvstrong12:2
....
...
msdhoni#yuvstrong12:255
msdhoni#yuvstrong12:256
musclenerd#pod2g:0
musclenerd#pod2g:1
此字段在其他一些行(所有重新分组即将结束)之后再次开始分组
justinbieber#pattiemallette:0
justinbieber#pattiemallette:1
justinbieber#pattiemallette:2
justinbieber#pattiemallette:3
justinbieber#scooterbraun:0
justinbieber#scooterbraun:1
justinbieber#scooterbraun:2
kaleycuoco#kunalnayyar:0
kaleycuoco#kunalnayyar:1
kaleycuoco#kunalnayyar:2
kaleycuoco#kunalnayyar:3
kaleycuoco#kunalnayyar:4
kaleycuoco#kunalnayyar:5
msdhoni#yuvstrong12:0
msdhoni#yuvstrong12:1
msdhoni#yuvstrong12:2
以上所有字段都在最后处于REGROUPED状态。他们似乎是相同的,但他们分组两次,因此出乎意料的结果。所有记录都不会发生这种情况。
我哪里错了?组字段是一个字符串。
谢谢!
答案 0 :(得分:0)
好的,MongoDB可以递归或部分调用MapReduce。因此,reduce函数应该是幂等的。
你会说我的reduce函数也是幂等的,因为值映射的结构是发射的,值reduce的结构返回是相同的。但是,需要注意的一点非常重要 - 无论何时迭代地进行调用,第一次调用的结果都将作为第二次调用的输入传递。
所以在我的情况下这个减少:
r = function(key, values) { var result = {count : 0}; values.forEach(function(value) { result.count++; }); return result; }
对同一个键的每次后续调用都将以0开始增量并添加1而不是添加从上一次迭代传递给它的计数作为value.count
所以不要做
result.count++;
我应该一直在做
result.count += value.count;
这样每次通话都会使用计数直到上次通话。
我不确定我是否正确解释了这一点,但这里有详细记载(在更多技术说明下):