pig:从一个分组包中取出所有元组

jpfvwuh4  于 2021-06-24  发布在  Pig
关注(0)|答案(3)|浏览(300)

我使用pig从元组生成组,如下所示:

  1. a1, b1
  2. a1, b2
  3. a1, b3
  4. ...
  5. ->
  6. a1, [b1, b2, b3]
  7. ...

这很简单,也很有效。但我的问题是得到以下结果:从获得的组中,我想生成组包中所有元组的集合:

  1. a1, [b1, b2, b3]
  2. ->
  3. b1,b2
  4. b1,b3
  5. b2,b3

如果我可以嵌套“foreach”,首先遍历每个组,然后遍历它的包,这将很容易。
我想我误解了这个概念,我将感谢你的解释。
谢谢。

mwg9r5ms

mwg9r5ms1#

看起来你需要一个笛卡尔积在袋子和它本身之间。要做到这一点,你需要使用扁平(袋)两次。
代码:

  1. inpt = load '.../group.txt' using PigStorage(',') as (id, val);
  2. grp = group inpt by (id);
  3. id_grp = foreach grp generate group as id, inpt.val as value_bag;
  4. result = foreach id_grp generate id, FLATTEN(value_bag) as v1, FLATTEN(value_bag) as v2;
  5. dump result;

请注意,大袋子会产生很多行。为了避免这种情况,可以在展平之前使用top(…):

  1. inpt = load '....group.txt' using PigStorage(',') as (id, val);
  2. grp = group inpt by (id);
  3. id_grp = foreach grp generate group as id, inpt.val as values;
  4. result = foreach id_grp {
  5. limited_bag = TOP(50, 0, values); -- all sorts of filtering could be done here
  6. generate id, FLATTEN(limited_bag) as v1, FLATTEN(limited_bag) as v2;
  7. };
  8. dump result;

对于特定的输出,可以在展平之前使用一些过滤:

  1. inpt = load '..../group.txt' as (id, val);
  2. grp = group inpt by (id);
  3. id_grp = foreach grp generate group as id, inpt.val as values;
  4. result = foreach id_grp {
  5. l = filter values by val == 'b1' or val == 'b2';
  6. generate id, FLATTEN(l) as v1, FLATTEN(values) as v2;
  7. };
  8. result = filter result by v1 != v2;

希望对你有帮助。
干杯

展开查看全部
xt0899hw

xt0899hw2#

与此相关的还有datafu udf库中的unorderedpairs函数。它生成一个包中所有项目的对(在您的情况下是您的分组包)

j8ag8udp

j8ag8udp3#

你可以用 GROUP ALL 要生成的pig语句

  1. A = -- Some bag
  2. B = -- Another bag
  3. groupedB = group B ALL;
  4. result = foreach A GENERATE
  5. TOTUPLE(*), groupedB.$1;
  6. -- Will generate
  7. ((a1), {(b1, b2, b3)})
  8. ((a2), {(b1, b2, b3)})
  9. ((a3), {(b1, b2, b3)})
  10. ...

相关问题