9

私のマッパーは、次のタプルを送信する必要があります。

<custID,prodID,rate>

そして、reduce フェーズで必要になるため、 custID をキーとして、値として prodID と rate を一緒にレデューサーに送信したいと考えています。これを行う最良の方法はどれですか?

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

2 に答える 2

13

最善の方法は CustomWritables を書くことです

これは double 値用です。それをテキストまたは文字列に変更できます

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

マッパーからは、次のように出力できます

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

お役に立てれば。

于 2014-08-23T07:04:59.373 に答える
3

私が考えることができる最も簡単な方法は、それらを単一の文字列にマージすることです。

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

次に、リデューサーにバックアップする場合は分割します。

マッパーからもう少しコードを投稿していただければ、より良い例を提供できるかもしれません。

更新:そうは言っても、あなたは最善の方法を求めました。最も正しい方法は、おそらく別のクラス グループを作成してprodIDまとめrateて送信することです。

于 2013-03-31T20:50:38.967 に答える