MongoDB MapReduce返回意外结果并分组两次

时间:2012-07-05 21:29:17

标签: mongodb mapreduce grouping

我正在使用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状态。他们似乎是相同的,但他们分组两次,因此出乎意料的结果。所有记录都不会发生这种情况。

我哪里错了?组字段是一个字符串。

谢谢!

1 个答案:

答案 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;

这样每次通话都会使用计数直到上次通话。

我不确定我是否正确解释了这一点,但这里有详细记载(在更多技术说明下):

http://www.mongodb.org/display/DOCS/MapReduce