簡體   English   中英

MongoDB中的MapReduce不會一次性減少所有具有相同密鑰的kv對

[英]MapReduce in MongoDB doesn't reduce all the k-v pairs with the same key in one go

我已經從csv導入了具有以下信息的數據庫:

  • 國家
  • 區域
  • 商品
  • 價錢
  • 日期

(這是csv: https//www.kaggle.com/jboysen/global-food-prices

CSV中的字符串按以下方式排序:

  • 國家1,地區1.1,商品X,價格,日期A
  • 國家1,區域1.1,商品X,價格,日期B
  • 國家1,區域1.1,商品Y,價格,日期A
  • 國家1,區域1.1,商品Y,價格,日期B
  • ...
  • 國家1,地區1.2,商品X,價格,日期A
  • 國家1,地區1.2,商品X,價格,日期B
  • 國家1,地區1.2,商品Y,價格,日期A
  • 國家1,地區1.2,商品Y,價格,日期B
  • ...
  • 國家2,地區2.1,商品X,價格,日期A
  • ...

我需要針對每個國家/地區,每種產品顯示最高價格。

我寫:

1)包含主要國家/地區和商品及價格價格的地圖

var map = function() {
   emit({country: this.country_name, commodity: this.commodity_name}, {price: this.price});
};

2)減少功能,可掃描與鑰匙相關的價格並檢查最高價格

var reduce = function(key, values) {

   var maxPrice = 0.0;

   values.forEach(function(doc) {
      var thisPrice = parseFloat(doc.price);
      if( typeof doc.price != "undefined") {
            if (thisPrice > maxPrice) {
               maxPrice = thisPrice; 
            }
      }
   });

   return {max_price: maxPrice};
};

3)我將地圖的輸出歸約到集合“ mr”

db.prices.mapReduce(map, reduce, {out: "mr"});

問題:

例如,如果我打開csv並通過以下方式手動排序:

  • 國家(升序)
  • 商品(訂單增加)
  • 價格(降序排列)

我可以檢查一下(以舉例說明)在阿富汗,商品面包的最高價格是65.25

但是,當我檢查MR時,得出阿富汗面包最高價格為0。

怎么了:

CSV中有10個區域記錄了阿富汗的面包記錄。 我在reduce的最后一行添加了:

print("reduce with key: " + key.country + ", " + key.commodity + "; max price: " + maxPrice);

從理論上講,如果我在mongodb日志中進行搜索,則應該只找到一個“減少鍵:阿富汗,面包;最高價格:???”的入口。 取而代之的是,我看到10條線(相同區域的數量),每條線的最高價格都不同。 最后一個具有“最高價格0”。

我的假設:

看起來,在發出之后,當調用reduce時,它不是在尋找具有相同密鑰的所有kv對,而是考慮了混雜的子組。

因此,回顧一下我在c​​sv結構上的初始示例:

  • 直到reduce掃描發出與“ afghanista,區域1,面包”相關的輸出,然后對它們進行歸約處理
  • 然后減少與“阿富汗,區域1,商品X”相關的輸出
  • 然后它又對與“阿富汗,區域2,面包”有關的輸出進行了另一種減少(而不是一次減少所有帶有阿富汗+面包的kv對)

我是否必須進行重新縮減以處理所有部分縮減職位?

我設法解決了這個問題。 MongoDB不必一口氣用相同的密鑰來還原所有kv對。

可能會發生這種情況(在這種情況下),MongoDB將對與特定鍵相關的kv對的子集執行約簡,然后在對與另一個鍵有關的另一個子集進行第二次約簡時,它將發送此第一個約簡的輸出。相同的鍵。

我的代碼無效,因為:

  • MongoDB對與鍵“阿富汗面包”相關的kv對子集進行了歸約,其輸出中的變量名為“ maxPrice”
  • MongoDB將繼續減少其他子集
  • 當遇到“阿富汗面包”的另一個子集時,MongoDB將采用第一個reduce的輸出,並將其用作值
  • 減少的輸出名為“ maxPrice”,但其他值稱為“ price”
  • 由於我要求輸入值“ doc.price”,因此當我掃描包含“ maxPrice”的文檔時,它將被忽略

有兩種方法可以解決此問題:

1)您為reduce輸出變量使用與發出輸出值相同的名稱

2)索引選擇為鍵的屬性,並在mapReduce()上使用“ sort”選項,以便與鍵相關的所有kv對一口氣減少

第二種方法是,如果您不想放棄使用其他名稱作為化簡輸出的名稱(加上它具有更好的性能,因為每個鍵只進行一個化簡)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM