0

我正在使用 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

上述所有字段都在最后重新分组。它们似乎相同,但它们分组了两次,因此产生了意想不到的结果。所有记录都不会发生这种情况。

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

谢谢!

4

1 回答 1

0

好的,MongoDB 可以递归或部分调用 MapReduce。因此,reduce 函数应该是幂等的。

你会说我的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

于 2012-07-05T22:36:11.433 回答