0

我想像这样使用 FOREACH:

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

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

我的意思是a用 的所有元素为叉积的每个元素制作b,然后执行一些自定义过滤并返回元组。

==编辑==

自定义过滤 = res_filtered = FILTER res BY ...; 生成 res_filtered。

==EDIT-2== 在没有事先 GROUP 或 COGROUP 的情况下,如何在 FOR 循环中使用嵌套的 CROSS 来做到这一点?

4

2 回答 2

2

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

如果您的过滤规则是

  • 如果a_attr以“Foo”开头并且b为 4,则接受
  • 如果a_attr以“Bar”开头并且b大于 17,则接受
  • 如果a_attr以 [mz] 中的字母开头并且b小于 0,则接受
  • 否则,拒绝

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

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

Pig 在JOINs 中删除空值,因此只有满足您的过滤条件的对才会通过。

于 2013-03-19T15:02:16.323 回答
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

如果你有,你不应该有(不必要的)过多的 IO 麻烦,因为在过滤FILTER之前将整个交叉产品写入磁盘。被过滤的记录永远不会被写入。CROSSCROSS

于 2013-03-19T13:06:56.877 回答