繁体   English   中英

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

[英]MongoDB MapReduce - Emit one key/one value doesnt call reduce

所以我是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(我正在使用)?

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

我意识到这是一个较老的问题,但我来到它并觉得我仍然不明白为什么这种行为存在以及如何构建map / reduce功能因此它不是问题。

MongoDB如果存在单个键实例则不调用reduce函数的原因是因为没有必要(我希望这会在一瞬间更有意义)。 以下是减少功能的要求

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

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

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

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

解:

  • 地图中添加了新字段:单个:0
  • reduce中将此字段更改为:single:1
  • finalize中检查此字段并执行必要的操作

     $map = new MongoCode("function() { var value = { time: this.time, email_id: this.email_id, single: 0 }; emit(this.email, value); }"); $reduce = new MongoCode("function(k, vals) { // make some need actions here return { time: vals[0].time, email_id: vals[0].email_id, single: 1 }; }"); $finalize = new MongoCode("function(key, reducedVal) { if (reducedVal.single == 0) { reducedVal.time = 11111; } return reducedVal; };"); 

“MongoDB不会为只有一个值的键调用reduce函数.values参数是一个数组,其元素是”映射“到键的值对象。”

http://docs.mongodb.org/manual/reference/command/mapReduce/#mapreduce-reduce-cmd

这是mapreduce的一般自然行为吗?

是。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM