2015-01-20 22 views
4

我有一個使用多個映射器和一個reducer的工作。映射器幾乎完全相同,只是它們用於產生結果的String的值不同。向每個映射器傳遞不同的參數

目前我有幾個類,String的每個值我提到—它感覺應該有一個更好的方式,這並不需要太多的代碼重複。有沒有辦法將這些String值作爲參數傳遞給映射器?

我的工作是這樣的:

Input File A ----> Mapper A using 
         String "Foo" ----+ 
             |---> Reducer 
        Mapper B using ----+ 
Input File B ----> String "Bar" 

我想要把它弄成這個樣子:

Input File A ----> GenericMapper parameterized 
           with String "Foo" ----+ 
                |---> Reducer 
        GenericMapper parameterized ----+ 
Input File B ---->   with String "Bar" 

編輯:這裏是我目前有兩個簡化的映射類。他們準確地代表我的實際情況。

class MapperA extends Mapper<Text, Text, Text, Text> { 
    public void map(Text key, Text value, Context context) { 
     context.write(key, new Text(value.toString() + "Foo")); 
    } 
} 

class MapperB extends Mapper<Text, Text, Text, Text> { 
    public void map(Text key, Text value, Context context) { 
     context.write(key, new Text(value.toString() + "Bar")); 
    } 
} 

編輯:每個映射器應該使用什麼字符串只取決於該文件中的數據從何而來。沒有辦法區分這些文件,除非通過文件名。

+0

一些實際的Mapper代碼很好,我想。或者至少你現在的Mapper結構 – maffelbaffel 2015-01-20 22:35:07

+0

@maffelbaffel我加了一些代碼。 – 2015-01-20 22:43:02

+0

除了附加字符串之外,映射器A與B的區別是什麼?你在使用多個輸入嗎?你有多少個文件? 從驅動程序代碼中,您可以傳遞與每個文件名關聯的「字符串」,並且可以從map()中獲取當前正在處理的文件名並追加必要的密鑰。 我相信我沒有完全得到這個問題。我錯過了什麼。 – 2015-01-21 03:05:42

回答

4

假設你使用的文件輸入格式,你可以得到你當前輸入文件名的映射是這樣的:

if (context.getInputSplit() instanceof FileSplit) { 
    FileSplit fileSplit = (FileSplit) context.getInputSplit(); 
    Path inputPath = fileSplit.getPath(); 
    String fileId = ... //parse inputPath into a file id 
    ... 
} 

您可以分析inputPath不過你想要的,如僅使用文件名或僅使用分區ID等來生成標識輸入文件的唯一ID。 例如:如規定以上,並獲得價值

conf.set("my.property.A", "foo"); 
conf.set("my.property.B", "bar"); 

在映射計算文件「ID」:

/some/path/A -> A 
/some/path/B -> B 

配置出你對驅動程序的每個可能的文件「ID」屬性

conf.get("my.property." + fileId); 
+0

我相信這和我評論的一樣:) – 2015-01-22 17:18:29

0

也許你會使用if語句在你的映射器中選擇字符串。什麼取決於使用一個或另一個字符串?

或者可能使用抽象映射器類。

0

也許這樣?

abstract class AbstractMapper extends Mapper<Text, Text, Text, Text> { 
    protected String text; 
    public void map(Text key, Text value, Context context) { 
     context.write(key, new Text(value.toString() + text)); 
    } 
} 
class MapperImpl1 extends AbstractMapper{ 
    @Override 
    public void map(Text key, Text value, Context context) { 
     text = "foo"; 
     super.map(); 
    } 
} 
class MapperImpl2 extends AbstractMapper{ 
     @Override 
     public void map(Text key, Text value, Context context) { 
      text = "bar"; 
      super.map(); 
     } 
    } 
+0

如果我沒有弄錯,這種方法將無助於將代碼減少到唯一的映射器類,因爲它仍然需要爲每個映射器類型定製實現。 – 2015-01-21 07:48:09

相關問題