2016-05-07 1 views
1

Это прослеживание вопрос о функции Extracting rows containing specific value using mapReduce and hadoop
MapperЧто именно выход картографа и редуктор функции

public static class MapForWordCount extends Mapper<Object, Text, Text, IntWritable>{ 

private IntWritable saleValue = new IntWritable(); 
private Text rangeValue = new Text(); 

public void map(Object key, Text value, Context con) throws IOException, InterruptedException 
{ 
    String line = value.toString(); 
    String[] words = line.split(","); 
    for(String word: words) 
    { 
     if(words[3].equals("40")){ 
      saleValue.set(Integer.parseInt(words[0])); 
      rangeValue.set(words[3]); 
      con.write(rangeValue , saleValue); 
     } 
    } 
} 
} 

функция Reducer

public static class ReduceForWordCount extends Reducer<Text, IntWritable, Text, IntWritable> 
{ 
    private IntWritable result = new IntWritable(); 
    public void reduce(Text word, Iterable<IntWritable> values, Context con) throws IOException, InterruptedException 
    { 
     for(IntWritable value : values) 
     { 
      result.set(value.get()); 
      con.write(word, result); 
     } 
    } 
} 

Выход полученный

40 105 
40 105 
40 105 
40 105 

EDIT 1: Но Ожидаемый выход

40 102 
40 104 
40 105 

Что я делаю неправильно?

Что именно происходит здесь в функции преобразователя и редуктора?

+0

вы выписывая пар ключ-значение ... Что больше вы хотите знать? –

+0

Спасибо за предложение @ cricket_007 Я определенно попробую это ... Я действительно хотел знать, ТОЧНО, что возвращает картер и редуктор - принимают и печатают. – user6119874

+1

, когда вы «расширьте» их, порядок «» для обоих классов. И выходные значения ключа отображения ** должны совпадать с входными ключевыми значениями редуктора –

ответ

1

В контексте original question - вам не нужен цикл не в картографа, ни в редукторе, как вы дублирующие записи:

public static class MapForWordCount extends Mapper<Object, Text, Text, IntWritable>{ 

private IntWritable saleValue = new IntWritable(); 
private Text rangeValue = new Text(); 

public void map(Object key, Text value, Context con) throws IOException, InterruptedException 
{ 
    String line = value.toString(); 
    String[] words = line.split(","); 
    if(words[3].equals("40")){ 
     saleValue.set(Integer.parseInt(words[0])); 
     rangeValue.set(words[3]); 
     con.write(rangeValue , saleValue); 
    } 
} 
} 

И в редукторе, как это было предложено в @Serhiy первоначальный вопрос вам нужно только одну строку кода:

public static class ReduceForWordCount extends Reducer<Text, IntWritable, Text, IntWritable> 
{ 
private IntWritable result = new IntWritable(); 
public void reduce(Text word, Iterable<IntWritable> values, Context con) throws IOException, InterruptedException 
{ 
    con.write(word, null); 
} 

пересортицы «Edit 1» - я оставлю это тривиальное практика :)

+0

Вы можете обратиться к @ cricket_007 ответу на * way *, который вы дублируете записи. –

1

Что именно происходит

Вы потребляете строки текст с разделителями запятыми, разделив запятыми, и отфильтровывать некоторые значения. con.write() следует вызывать только один раз в строке, если все, что вы делаете, - это извлечение только этих значений.

Картограф сгруппирует все ключи «40», которые вы выведете, и сформируйте список всех значений, которые были написаны с помощью этого ключа. И это то, что редуктор читает.

Возможно, вы должны попробовать это для своей функции карты.

// Set the values to write 
saleValue.set(Integer.parseInt(words[0])); 
rangeValue.set(words[3]); 

// Filter out only the 40s 
if(words[3].equals("40")) { 
    // Write out "(40, safeValue)" words.length times 
    for(String word: words) 
    { 
     con.write(rangeValue , saleValue); 
    } 
} 

Если вы не хотите, повторяющихся значений для длины разделенной строки, а затем избавиться от для цикла.

Весь ваш редуктор делает только распечатку того, что он получил от картографа.

0

выход Mapper будет что-то вроде этого:

<word,count> 

выход Reducer будет выглядеть так:

<unique word, its total count> 

Например: линия читается и все слова в ней подсчитываются и положить в <key,value> пара:

<40,1> 
<140,1> 
<50,1> 
<40,1> .. 

здесь 40,50,140, ​​.. все ключи и значение является счетчиком ню mber появления этого ключа в строке. Это происходит в картографе.

Затем эти пары key,value отправляются на редуктор, где схожие ключи сводятся к одному key, и все значения, ассоциированные с этим ключом, суммируются, чтобы дать значение паре ключ-значение.Таким образом, результат редуктора будет что-то вроде:

<40,10> 
<50,5> 
... 

В вашем случае редуктор ничего не делает. Уникальные значения/слова, найденные картографом, выдаются только как результат.

В идеале вы должны уменьшить & получить выход вроде: «40,150» был найден 5 раз в той же строке.