我想使用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再做一次?
答案 0 :(得分:2)
根据过滤的具体情况,您可以在a
和b
中设计一组有限的不相交元素,然后在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问题。过滤的记录根本不会被写入。