我是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);
所以任何人都可以。给我一些关于剧本的帮助?
答案 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;