2016-05-07 4 views
1

Dies ist ein Follow-up-Frage von Extracting rows containing specific value using mapReduce and hadoop
Mapper FunktionWas genau Ausgabe von Mapper und Minderer Funktion ist

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 Funktion

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); 
     } 
    } 
} 

Ausgabe erhalten wird

40 105 
40 105 
40 105 
40 105 

EDIT 1: Aber die erwartete Ausgabe ist

40 102 
40 104 
40 105 

Was mache ich falsch?

Was genau passiert hier in Mapper und Reducer-Funktion?

+0

Sie schreiben Schlüssel Wert-Paare aus ... Was mehr willst du wissen? –

+0

Danke für den Vorschlag @ cricket_007 Ich werde es auf jeden Fall versuchen ... Ich wollte eigentlich wissen, was GENAU Mapper zurück und Reducer - akzeptieren und drucken. – user6119874

+1

Wenn Sie sie 'erweitern', lautet die Reihenfolge '' für beide Klassen. Und die Ausgabe-Schlüssel-Werte des Mappers ** müssen ** den Eingabe-Schlüssel-Werten des Reduzierers entsprechen –

Antwort

1

Im Rahmen der original question - Sie brauchen, um die Schleife nicht nicht in der Mapper noch im Minderer, wie Sie die Duplizieren Einträge sind:

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); 
    } 
} 
} 

Und im Minderer, in wie @Serhiy vorgeschlagen die ursprüngliche Frage, die Sie nur eine Zeile Code benötigen:

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“ Herabstufung - ich werde es eine triviale Übung lassen :)

+0

Sie können auf @ cricket_007 antworten wie * duplizieren * Einträge *. –

1

Was genau

Sie verbrauchen Linien kommagetrennte Text geschieht, die Kommas aufzuteilen, und einige Werte herausgefiltert werden. con.write() sollte nur einmal pro Zeile aufgerufen werden, wenn Sie nur diese Werte extrahieren.

Der Mapper gruppiert alle ausgegebenen "40" -Tasten und bildet eine Liste aller Werte, die mit diesem Schlüssel geschrieben wurden. Und genau das liest der Reducer vor.

Sie sollten dies wahrscheinlich für Ihre Kartenfunktion versuchen.

// 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); 
    } 
} 

Wenn Sie keine doppelten Werte für die Länge der aufgeteilten Zeichenfolge benötigen, dann entfernen Sie die for-Schleife.

Alles, was Ihr Reducer macht, ist nur das auszudrucken, was er vom Mapper erhalten hat.

0

Mapper Ausgabe wird in etwa so aussehen:

<word,count> 

Reducer Ausgabe wie folgt sein würde:

<unique word, its total count> 

Beispiel: Eine Zeile gelesen wird und alle Wörter in ihm werden gezählt und in eine setzen <key,value> Paar:

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

hier 40,50,140, ​​.. sind alle Schlüssel und der Wert ist die Anzahl der nu Anzahl der Vorkommen dieses Schlüssels in einer Zeile. Dies geschieht im Mapper.

Dann werden diese key,value Paare an den Reduzierer gesendet, wo alle ähnlichen Schlüssel auf einen einzigen key reduziert werden und alle mit diesem Schlüssel assoziierten Werte addiert werden, um dem Schlüssel/Wert-Paar einen Wert zu geben.Also, das Ergebnis des Reduzierers wäre etwas wie:

In Ihrem Fall tut der Reducer nichts. Die vom Mapper gefundenen eindeutigen Werte/Wörter werden nur als Ausgabe ausgegeben.

Im Idealfall sollten Sie reduzieren & bekommen eine Ausgabe wie: "40,150" wurde 5 mal auf der gleichen Linie gefunden.