如何在Pig中按列加入和过滤2个关系?

时间:2017-08-17 10:36:41

标签: apache-pig

我是Pig脚本的新手,并尝试修改一些现有的pig脚本以从日志文件中提取一些数据。

E.g。我有2个日志文件,其中一个模式为:

message Class {
    message Student {
        optional int32 uid = 1;
        optional string name = 2;
    }
    optional int32 cid = 1;
    repeated Student students = 2;
}

加载后,我认为创建了一个包(比如bag1)(如果我错了,请纠正我):

bag1:
{
(uid1, {(cid11, name11), (cid12, name12), (cid13, name13), ...}),
(uid2, {(cid21, name21), (cid22, name22), (cid23, name23), ...}),
...
}

另一个日志文件很简单,生成的包(bag2)就是这样。

bag2:
{
(name11),
(name13),
(name22),
...
}

我想要的是,如果bag2中的任何名字包含在行内,请从bag1获取所有行,例如:

result bag:
{
(uid1, (name11, name13)),
(uid2, (name22)),
}

我想我需要在这2个包上做一些加入/过滤,但不知道怎么做。 我尝试了下面的脚本片段,但它甚至不是一个有效的脚本。

res = FOREACH bag1 {
        names = FOREACH students GENERATE name;
        xnames = JOIN names by name, bag2 by name;
        GENERATE cid, xnames;
};
FILTER res BY not IsEmpty(xnames);

所以任何人都可以。给我一些关于剧本的帮助?

1 个答案:

答案 0 :(得分:0)

您无法在嵌套JOIN中使用FOREACH,您可以尝试展平您的元组,然后将其与第二个表连接:  

bag1_flat = FOREACH bag1 GENERATE $0 AS uid, FLATTEN($1);
bag1_flat = FOREACH bag1_flat GENERATE uid, $2 AS name;

内部联接,将过滤行:

bag12 = JOIN bag1_flat by name, bag2 by $0;
bag12 = FOREACH bag12 GENERATE bag1_flat::uid AS uid, bag1_flat::name AS name;

最后,根据你的说法,你不会得到元组,因为它们不能有不同的尺寸,你会得到袋子:

bag12_group = GROUP bag12 BY uid;
res = FOREACH bag12_group GENERATE group AS uid, bag12.name AS names;