2013-03-31 10 views
8

Moja odwzorowujący musi przesłać następujące krotki:Jak Java Hadoop Mapper mogą wysyłać wiele wartości

<custID,prodID,rate> 

I chcę wysłać do reduktor z custid jako klucza, jak i wartości, prodid i stopy razem, jak są potrzebne do fazy redukcji. Jaki jest najlepszy sposób na zrobienie tego?

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

    String[] col = value.toString().split(","); 
    custID.set(col[0]); 
    data.set(col[1] + "," + col[2]); 
    context.write(custID, data); 
} 

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

    for (Text val : values) { 
     String[] temp = val.toString().split(","); 
     Text rate = new Text(temp[1]); 
     result.set(rate); 
     context.write(key, result); 
    } 
} 
+0

Dlaczego nie możesz wysłać wielu wartości? Nic nie ogranicza liczby par klucz-wartość, które może wytworzyć jedno zadanie mapy. – kichik

Odpowiedz

3

Najprostszym mogę myśleć tylko połączyć je w jeden ciąg:

output.collect(custID, prodID + "," + rate); 

Następnie podzielić jeśli z powrotem na reduktorów.

Jeśli opublikujesz nieco więcej kodu ze swojego narzędzia odwzorowującego, być może moglibyśmy dać lepszy przykład.

AKTUALIZACJA: To powiedziawszy, zapytałeś o drogę najlepszy. Najodpowiedniejszym sposobem jest prawdopodobnie utworzenie osobnego grupowania klas razem: prodID i rate i wysłanie tego.

+0

Próbuję tego rozwiązania (aby je scalić), ale gdy w reduktor używam String v = val.toString(). Split (","); polecenie rozdzielić ciąg, mogę używać v [0] regularnie, ale kiedy używam wartości v [1] otrzymuję wyjątek "array out of bounds". –

+0

Czy możesz zamieścić jakiś kod (na oryginalnym pytaniu, lub pastebin/github) na to, co aktualnie masz? –

+0

Dodałem kod, dzięki. –

11

Najlepszym sposobem jest napisać CustomWritables

To dla podwójnej wartości. Można to zmienić na tekst lub String

import java.io.DataInput; 
import java.io.DataOutput; 
import java.io.IOException; 
import org.apache.hadoop.io.Writable; 


/** 
* @author Unmesha SreeVeni U.B 
* 
*/ 
public class TwovalueWritable implements Writable { 
    private double first; 
    private double second; 

    public TwovalueWritable() { 
     set(first, second); 
    } 
    public TwovalueWritable(double first, double second) { 
     set(first, second); 
    } 
    public void set(double first, double second) { 
     this.first = first; 
     this.second = second; 
    } 
    public double getFirst() { 
     return first; 
    } 
    public double getSecond() { 
     return second; 
    } 
    @Override 
    public void write(DataOutput out) throws IOException { 
     out.writeDouble(first); 
     out.writeDouble(second); 
    } 
    @Override 
    public void readFields(DataInput in) throws IOException { 
     first = in.readDouble(); 
     second = in.readDouble(); 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     long temp; 
     temp = Double.doubleToLongBits(first); 
     result = prime * result + (int) (temp^(temp >>> 32)); 
     temp = Double.doubleToLongBits(second); 
     result = prime * result + (int) (temp^(temp >>> 32)); 
     return result; 
    } 
    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof TwovalueWritable)) { 
      return false; 
     } 
     TwovalueWritable other = (TwovalueWritable) obj; 
     if (Double.doubleToLongBits(first) != Double 
       .doubleToLongBits(other.first)) { 
      return false; 
     } 
     if (Double.doubleToLongBits(second) != Double 
       .doubleToLongBits(other.second)) { 
      return false; 
     } 
     return true; 
    } 
    @Override 
    public String toString() { 
     return first + "," + second; 
    } 
} 

I od odwzorowującym można po prostu emitują go jako

context.write(key,new TwovalueWritable(prodID,rate)); 

nadzieję, że to pomaga.

+0

jego dobre rozwiązania, ale utknąłem z ciągiem, jak zastąpić metodę równą ... –

+0

@RaviHTapela: Jeśli korzystasz z Eclipse IDE - równa się, hashCode może być generowany automatycznie –