2

这与确定一个关系中元组中的 int 值是否是 Pig Latin 中另一个关系中的列的成员值有关。我是 Pig Latin 的新手,我发现很难将我的思想包裹在框架上。

目前我有两个表,一个包含针对具有小值域的标签的 id 列表,另一个包含包含 id 和引用另一个表的标签 id 的元组。

这是orders.csv:

标识,标签

第1597章

999,是的

787,一个

第812章

和tags.csv:

id, tag_id

11, 55

99, 812

22, 787

我需要一种方法来确定订单表中所有元组的 tag_id 是否是标记表的 id 子集的成员。

id, has_x

111, 0

99, 1

22, 0

这是我到目前为止所拥有的:

使用 jython 作为任务注册 's3://bucket/jython_task.py';

tags = load 's3://bucket/tags.csv' USING PigStorage(',') AS (i​​d: long, tag: chararray);

orders = load 's3://bucket/orders.csv' USING PigStorage(',') AS (i​​d: long, tag_id: long);

tags = 按标签过滤标签 == 'x';

x_cases = foreach 标签生成标签;

tagged_orders = foreach 订单生成 id, tag_id, tasks.check_membership(tag_id, x_cases.tag) as is_x:int;

和 udf:

def check_membership(instance, value_list):
if instance != None:
    for value in value_list:
        if instance == value[0]:
            return 1
return 0

我得到错误:

2012-09-20 23:53:45,377 [main] 错误 org.apache.pig.tools.pigstats.SimplePigStats - 错误 2997:无法从支持的错误重新创建异常:org.apache.pig.backend.executionengine.ExecException:错误0:标量在输出中多于一行。第一名:(7995),第二名:(8028)

我究竟做错了什么?有没有更好的方法来做我想做的事情?

4

2 回答 2

0

我最终找到了解决我自己问题的方法,它涉及针对这两个关系的左外连接,并且可能有一个更优雅的解决方案,我愿意接受任何更好的解决方案。

tags = load 's3://bucket/tags.csv' USING PigStorage(',') AS (i​​d: long, tag: chararray);

orders = load 's3://bucket/orders.csv' USING PigStorage(',') AS (i​​d: long, tag_id: long);

tags = 按标签过滤标签 == 'x';

tag_cases = foreach标签生成id,1为found_tag:int;

tag_cases = 不同的 tag_cases;

示例 = 按 o_id 加入订单,按 id 离开外部 tag_cases;

example = foreach 示例生成 orders::o_id 作为 id, (tag_cases is null ? 0 : 1) as has_tag;

于 2012-09-24T11:02:55.637 回答
0

我不知道 UDF 有什么问题,但你可以用纯 PIG 得到结果。使用COGROUPIsEmpty内置函数。

x_cases = cogroup orders by (tag_id), tags by (id);
tagged_orders = foreach x_cases generate flatten(orders), IsEmpty(tags);

或者

tagged_orders = filter x_cases by not IsEmpty(tags);

它可能不是运行速度最快的实现,因为它使用 Reduce 侧连接,但这完全取决于卷。

一种更快的方法可能是使用复制连接,它将标签表加载到 RAM 中,并使用更快的 Map 侧连接。坏事是您将丢失未标记的记录。

tagged_orders = join orders by (tag_id), tags by (id) using 'replicated';
于 2012-09-21T10:52:52.233 回答