![](/img/trans.png)
[英]MapReduce in MongoDB doesn't reduce all the k-v pairs with the same key in one go
[英]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函數中的單個聚合結果。
解:
在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.