MongoDB MapReduce - 发出一个键/一个值不调用reduce

Iam*_*ght 19 mapreduce mongodb pymongo

所以我是mongodb和mapreduce的新手,并且遇到了这个"怪癖"(或者至少在我看来是个怪癖)

假设我的集合中有对象如下:

{'key':5,'value':5}

{'key':5,'value':4}

{'key':5,'value':1}

{'key':4,'value':6}

{'key':4,'value':4}

{'key':3,'value':0}

我的地图功能只是发出键和值

我的reduce函数只是在返回它们之前添加了值AND并添加1(我这样做是为了检查是否甚至调用了reduce函数)

我的结果如下:

{'_ id':3,'值':0 }

{'_ id':4,'价值':11.0}

{'_ id':5,'价值':11.0}

正如你所看到的,对于键4和5,我得到了键3的预期答案11 BUT(在该键的集合中只有一个条目)我得到了意想不到的0!

这是mapreduce的一般自然行为吗?对于MongoDB?对于pymongo(我正在使用)?

Jen*_*nna 37

reduce函数将具有相同键的文档合并到一个文档中.如果map函数为特定键发出单个文档(与键3的情况一样),则不会调用reduce函数.

  • 需要明确的是,这是map reduce的设计方式.如果您想使用唯一键修改文档(如键3),请考虑使用finalize函数:http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-FinalizeFunction (10认同)
  • 如果我们想在结果中包含单个文档的密钥,那么解决方案是什么? (3认同)

sen*_*nfo 5

我意识到这是一个较旧的问题,但我来到它并觉得我仍然不明白为什么会存在这种行为以及如何构建映射/减少功能,所以这不是问题。

如果有一个键的单个实例,MongoDB 不调用 reduce 函数的原因是因为它没有必要(我希望稍后会更有意义)。以下是reduce 函数的要求

  • reduce 函数必须返回一个对象,其类型必须map 函数发出的值的类型相同
  • valuesArray 中元素的顺序不应影响reduce 函数的输出
  • reduce 函数必须是幂等的。

第一个要求非常重要,似乎很多人都忽略了它,因为我看到很多人在 reduce 函数中映射,然后在 finalize 函数中处理单键情况。然而,这是解决问题的错误方法。

可以这样想:如果一个键只有一个实例,一个简单的优化就是完全跳过reducer(没有什么可以reduce)。单键值仍然包含在输出中,但reducer 的目的是构建集合中多键文档的聚合结果。如果 mapper 和 reducer 输出相同的类型,您应该通过查看map/reduce 函数输出的对象结构而完全不知道。您不应该使用 finalize 函数来纠正未通过减速器运行的对象的结构。

简而言之,在您的 map 函数中进行映射,并在您的 reduce 函数中将多键值减少为单个聚合结果。