如何在pig中按列连接和过滤2个关系?

ybzsozfc  于 2021-06-24  发布在  Pig
关注(0)|答案(1)|浏览(315)

我是pig脚本的新手,尝试修改一些现有的pig脚本,从日志文件中提取一些数据。
e、 g.我有两个日志文件,其中一个模式为:

  1. message Class {
  2. message Student {
  3. optional int32 uid = 1;
  4. optional string name = 2;
  5. }
  6. optional int32 cid = 1;
  7. repeated Student students = 2;
  8. }

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

  1. bag1:
  2. {
  3. (uid1, {(cid11, name11), (cid12, name12), (cid13, name13), ...}),
  4. (uid2, {(cid21, name21), (cid22, name22), (cid23, name23), ...}),
  5. ...
  6. }

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

  1. bag2:
  2. {
  3. (name11),
  4. (name13),
  5. (name22),
  6. ...
  7. }

我想要的是,如果行中包含bag2中的任何名称,则从bag1获取所有行,如:

  1. result bag:
  2. {
  3. (uid1, (name11, name13)),
  4. (uid2, (name22)),
  5. }

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

  1. res = FOREACH bag1 {
  2. names = FOREACH students GENERATE name;
  3. xnames = JOIN names by name, bag2 by name;
  4. GENERATE cid, xnames;
  5. };
  6. FILTER res BY not IsEmpty(xnames);

任何人都可以。在剧本上给我点帮助?

bpzcxfmw

bpzcxfmw1#

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

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

内部联接将过滤行:

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

最后,按uid分组您将不会得到元组,尽管它们的大小不能不同,您将得到包:

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

相关问题