2013-01-25 2 views
1

SQL GroupBy와 비슷한 기능을하는 코드를 작성했습니다.reducer-MapReduce에 여러 인수 보내기

내가했다 데이터 세트가 여기에 있습니다 :


25078868141920090906200937200909,619, 일요일, 주말, ON-NET 나가는 아침, VOICE, 25078, PAY_AS_YOU_GO_PER_SECOND_PSB, 성공적인-RELEASEDBYSERVICE, 그 값을 합계하는 감속기에 제 17 인자를 전송로 매퍼

public class MyMap extends Mapper<LongWritable, Text, Text, DoubleWritable> { 

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

     String line = value.toString(); 
     String[] attribute=line.split(","); 
     double rs=Double.parseDouble(attribute[17]); 

     String comb=new String(); 
     comb=attribute[5].concat(attribute[8].concat(attribute[10])); 

      context.write(new Text(comb),new DoubleWritable (rs)); 

    } 
} 
public class MyReduce extends Reducer<Text, DoubleWritable, Text, DoubleWritable> { 

protected void reduce(Text key, Iterator<DoubleWritable> values, Context context) 
      throws IOException, InterruptedException { 

      double sum = 0; 
      Iterator<DoubleWritable> iter=values.iterator(); 
       while (iter.hasNext()) 
       { 
        double val=iter.next().get(); 
        sum = sum+ val; 
       } 
       context.write(key, new DoubleWritable(sum)); 
     }; 
    } 


17,0,1,21.25,635-10-112-30455. 이제 저는 감속기에 어떻게 보내야합니까?

답변

2

데이터 유형이 동일하면 ArrayWritable 클래스를 만들어야합니다. 이 클래스는 유사합니다 : 당신이 지금 DblArrayWritable의 값을 반복 할 수 있어야합니다 당신의 감속기에

public class MyMap extends Mapper<LongWritable, Text, Text, DblArrayWritable> 
{ 
    public void map(LongWritable key, Text value, Context context) throws IOException 
    { 

    String line = value.toString(); 
    String[] attribute=line.split(","); 
    DoubleWritable[] values = new DoubleWritable[2]; 
    values[0] = Double.parseDouble(attribute[14]); 
    values[1] = Double.parseDouble(attribute[17]); 

    String comb=new String(); 
    comb=attribute[5].concat(attribute[8].concat(attribute[10])); 

    context.write(new Text(comb),new DblArrayWritable.set(values)); 

    } 
} 

: 같은

public class DblArrayWritable extends ArrayWritable 
{ 
    public DblArrayWritable() 
    { 
     super(DoubleWritable.class); 
    } 
} 

귀하의 매퍼 클래스는 다음 보인다.

그러나 샘플 데이터에 따라 유형이 다를 수 있습니다. 트릭을 수행 할 수있는 ObjectArrayWritable 클래스를 구현할 수는 있지만 확실하지는 않습니다. 지원하지 않을 수 있습니다. 그것이 작동하는 경우 클래스는 다음과 같습니다

public class ObjArrayWritable extends ArrayWritable 
{ 
    public ObjArrayWritable() 
    { 
     super(Object.class); 
    } 
} 

당신은 단순히 값을 연결 한 후 다시 분할 할 감속기에 텍스트로 전달하여이 문제를 해결할 수 있습니다.

또 다른 옵션은 자신의 Writable 클래스를 구현하는 것입니다. 작동 방식에 대한 샘플은 다음과 같습니다.

public static class PairWritable implements Writable 
{ 
    private Double myDouble; 
    private String myString; 

    // TODO :- Override the Hadoop serialization/Writable interface methods 
    @Override 
    public void readFields(DataInput in) throws IOException { 
      myLong = in.readDouble(); 
      myString = in.readUTF(); 
    } 

    @Override 
    public void write(DataOutput out) throws IOException { 
      out.writeDouble(myLong); 
      out.writeUTF(myString); 
    } 

    //End of Implementation 

    //Getter and Setter methods for myLong and mySring variables 
    public void set(Double d, String s) { 
     myDouble = d; 
     myString = s; 
    } 

    public Long getLong() { 
     return myDouble; 
    } 
    public String getString() { 
     return myString; 
    } 

}