是否可以在猪拉丁语中制作没有COGROUP的嵌套FOREACH?

时间:2013-03-11 16:50:36

标签: foreach nested apache-pig

我想使用FOREACH,如:

a:{a_attr:chararray}
b:{b_attr:int}

FOREACH a {
  res = CROSS a, b;
  -- some processing
  GENERATE res;
}

我的意思是为a的每个元素添加一个包含b所有元素的交叉产品,然后执行一些自定义过滤并返回元组。

== EDIT ==

Custom filetering = res_filtered = FILTER res BY ...; 生成res_filtered。

== EDIT-2 == 如何在没有先前的GROUP或COGROUP的情况下在FOR循环中使用嵌套的CROSS再做一次?

2 个答案:

答案 0 :(得分:2)

根据过滤的具体情况,您可以在ab中设计一组有限的不相交元素,然后在JOIN上设计这些元素。例如:

如果您的过滤规则是

  • 如果a_attr以“Foo”开头且b为4,则接受
  • 如果a_attr以“条形码”开头且b大于17,则接受
  • 如果a_attr以[m-z]中的字母开头且b小于0,则接受
  • 否则,拒绝

然后你可以编写一个UDF,它将为满足第一个规则的项返回1,为第二个规则返回2,为第三个规则返回3,否则返回NULL。您的CROSS / FILTER将成为

res = JOIN a BY myUDF(a), b BY myUDF(b);

Pig会在JOIN s中删除空值,因此只会传递满足过滤条件的对。

答案 1 :(得分:1)

CROSS生成每个关系中所有元组的交叉积。所以不需要嵌套FOREACH。只需执行CROSS然后FILTER

a: {a_attr: chararray}
b: {b_attr: int}

crossed = CROSS a, b;
crossed: {a::a_attr: chararray,b::b_attr: int}

res = FILTER crossed BY ... -- your custom filtering

如果FILTER之后紧跟CROSS,则在过滤之前CROSS将整个交叉产品写入磁盘时,不应有(不必要的)过多的IO问题。过滤的记录根本不会被写入。