Hadoop - 为单个密钥生成多个值

Ram*_*esh 5 hadoop hadoop-partitioning

我能够成功地改变hadoop中的wordcount程序以满足我的要求.但是,我有另一种情况,我在3个值中使用相同的键.假设我的输入文件如下所示.

A Uppercase 1 firstnumber  I  romannumber a lowercase
B Uppercase 2 secondnumber II romannumber b lowercase
Run Code Online (Sandbox Code Playgroud)

目前在我的map/reduce程序中,我正在做类似下面的事情.这里A是键,1是值.

A 1
Run Code Online (Sandbox Code Playgroud)

我需要我的地图缩小来执行类似下面的操作.

A 1 I a 
Run Code Online (Sandbox Code Playgroud)

我可以在3个不同的程序中执行它们,如下所示,可以生成输出.

A 1
A I
A a
Run Code Online (Sandbox Code Playgroud)

但是,我希望他们在一个程序中自己做.基本上,从我的地图功能我想做到这一点.

context.write(key,value1);
context.write(key,value2);
context.write(key,value3);
Run Code Online (Sandbox Code Playgroud)

有什么方法可以在同一个程序中完成而不是编写三个不同的程序吗?

编辑:

让我提供一个更清晰的例子.我需要做类似下面的事情.

A uppercase 1 firstnumber  1.0 floatnumber str stringchecking
A uppercase 2 secondnumber 2.0 floatnumber ing stringchecking
Run Code Online (Sandbox Code Playgroud)

我的最终输出是,

A 3 3.0 string
Run Code Online (Sandbox Code Playgroud)

3是两个整数的和,3.0是浮点数的总和,字符串是两个字符串的串联.

Mik*_*ark 15

首先,您需要一个可写的所有三个值的复合.

public class CompositeWritable implements Writable {
    int val1 = 0;
    float val2 = 0;
    String val3 = "";

    public CompositeWritable() {}

    public CompositeWritable(int val1, float val2, String val3) {
        this.val1 = val1;
        this.val2 = val2;
        this.val3 = val3;
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        val1 = in.readInt();
        val2 = in.readFloat();
        val3 = WritableUtils.readString(in);
    }

    @Override
    public void write(DataOutput out) throws IOException {
        out.writeInt(val1);
        out.writeFloat(val2);
        WritableUtils.writeString(out, val3);
    }

    public void merge(CompositeWritable other) {
        this.val1 += other.val1;
        this.val2 += other.val2;
        this.val3 += other.val3;
    }

    @Override
    public String toString() {
        return this.val1 + "\t" + this.val2 + "\t" + this.val3;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的减少你会做这样的事情......

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

    CompositeWritable out;

    for (CompositeWritable next : values)
    {
        out.merge(next);
    }

    ctx.write(key, out);
}
Run Code Online (Sandbox Code Playgroud)

您的映射器将只CompositeWritable为每个地图输出一个.

我没有尝试编译这个,但总的想法就在那里.