如何在hadoop猪中依次加入关系?

时间:2013-05-23 09:08:13

标签: join hadoop apache-pig

我有一个这样的行数据:

a\tb1,b2,..,bn\tc1,c2,..,cn

其中n是不确定的。而现在,我想把它变成这样的一些行:

a\tb1\tc1
a\tb2\tc2
...
a\tbn\tcn

猪拉丁有可能,还是必须使用UDF? 如果使用脚本:

A = LOAD 'file' AS (a, b, c);
B = FOREACH A GENERATE a, FLATTEN(TOKENIZE(b)), FLATTEN(TOKENIZE(c));
dump B;

我将得到如下结果:

a\tb1\tc1
a\tb1\tc2
..
a\tb1\tcn
a\tb2\tc1
a\tb2\tc2
..
a\tb2\tcn
..

这不是我想要的数据。有没有人有想法?

2 个答案:

答案 0 :(得分:1)

IMO太多使用Pig的人都不耐写UDF。在您的情况下,您需要执行此操作的UDF非常简单。这是示例代码(未经测试)

public class InSequenceJoin extends EvalFunc<DataBag>
{
    public DataBag exec(Tuple input) throws IOException {
        String b = (String) input.get(0);
        String c = (String) input.get(1);
        String[] bArray = b.split(",");
        String[] cArray = c.split(",");
        DataBag bag = BagFactory.getInstance().newDefaultBag();
        for (int i = 0; i < bArray.length && i < cArray.length; i++) {
            Tuple tuple = TupleFactory.getInstance.newTuple(2);
            tuple.set(0, bArray[i]);
            tuple.set(1, cArray[i]);
            bag.add(tuple);
        }
        return bag;
    }
}

define InSequenceJoin mysourcepath.InSequenceJoin();
A = LOAD 'file' AS (a, b, c);
B = FOREACH A GENERATE a, FLATTEN(InSequenceJoin(b,c));
dump B;

如果您需要在UDF中,您可以添加有关数组大小是否匹配的验证。您可以将我在示例中使用的String split替换为您真正需要的任何内容。

答案 1 :(得分:0)

我尝试使用datafu的包UDF。

按照您的方式加载数据,然后使用Enumerate枚举bag元素,然后展平(这样就可以看到你看到的bag元素之间的交叉连接)然后你可以过滤添加到的数据包袋子元素。

见这里:https://github.com/linkedin/datafu