2017-06-22 96 views
0

我的數據結構如下:如何查找hadoop數據集中所有鍵的組合?

A, 23 
B, 324235 
C, 123 
D, 213 

的示例字計數映射器具有以下映射函數簽名:

public void map(Object key, Text value, Context context 
        ) throws IOException, InterruptedException { 

核心問題:

Text value是一個簡單的單個線來自輸入文件或單個鍵。我如何一次訪問所有的密鑰?看來線路(和他們的後來減少擴張)不知道其他的輸入線

實例應用:

我期待輸出ID的所有組合,這需要的鑰匙以「瞭解對方的」

AB 
AC 
AD 
BC 
BD 
CD 

編輯:幼稚的做法/直覺

一種方式來完成它,我相信是使用映射到項目中的每個線映射到相同的密鑰,然後在減速映射的

結果:

CONST_KEY, A 
CONST_KEY, B 
CONST_KEY, C 
CONST_KEY, D 

減速機:

public void reduce(Text key, Iterable<Text> values, Context context){ 

//PSEUDO CODE 
    for(int i = 0; i < values.length; i++){ 
     for(int j = i+1; j < values.length; j++){ 
      String combo = concat(values[i], values[j]); 
     } 
    } 
} 

但這似乎瘋狂的效率不高

+2

此問題適合從MapReduce生成的排列類別。請參閱https://stackoverflow.com/questions/6535878/permutations-with-mapreduce。 –

+0

更糟糕的是,您編寫reduce的方式無法正常工作,因爲您無法像那樣訪問'values'。 Hadoop不允許你訪問值列表,你可以迭代一次值。如果你想要做更多,你需要將它們存儲在記憶中。 –

回答

0

我只是得到鍵集,然後做一個嵌套for循環來創建結果:

List<String> keys = new ArrayList<String>(yourmap.keySet()); 
List<String> results= new ArrayList<String>(); 

for(int i = 0; i < keys.length - 1; i++) 
    for (int j = i+1; j < keys.length; j++) { 
     results.add(keys.get(i) + keys.get(j)) 
    } 
} 
+0

如果你可以在內存中讀取整個文件,但它似乎不會擴展到hadoop使用的map reduce模型,除非我錯過了一些非常明顯的東西(我的錯誤是我的原始問題標題太過模糊,因爲編輯過了) – James

0

你可能至少有三個選項來實現這一目標:

  1. WholeFileInputFormat

你可以寫一個自定義輸入格式,這給整個文件的記錄。你可以在他的Hadoop書here的Tom Whites代碼中看到這個例子。

  • 在映射器
  • 保持狀態由於每個記錄進入映射器,隨着每次迭代生成新的組合。或者更簡單的方法是將記錄添加到列表中,並且一旦讀取了所有記錄,則使用Mapper的cleanup()方法生成所有組合。

  • 使用減速
  • 你可以發射從映射的每個條目,使用公共密鑰和所有值將進入減少,你可以重複值的列表通過。然後你需要有邏輯來產生所有的組合。

    問題是,如果你有多個文件,因此多個mappers並行運行,12不工作。只要唯一的一組鍵將適合內存,3就會工作。