2012-09-21 39 views
2

int的成员这是相对于确定是否从在一个关系的元组int值是从猪拉丁另一关系的柱的部件值。我是Pig Latin的新手,发现很难将我的思想包围在框架中。确定在一个单独的关系

目前我有两个表,一个包含ID的对标签列表与值的小区域,另一个含有一个ID和标签ID参照其他表的元组。

这里的orders.csv:

id, tag

1597, x

999, y

787, a

812, x

而且tags.csv:

id, tag_id

11, 55

99, 812

22, 787

我需要锻炼的方法,如果在订单表中的所有元组的TAG_ID是的一员标签表的ID的子集。

id, has_x

111, 0

99, 1

22, 0

这是我到目前为止有:

register 's3://bucket/jython_task.py' using jython as task;

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

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

tags = filter tags by tag == 'x';

x_cases = foreach tags generate tag;

tagged_orders = foreach orders generate 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] ERROR org.apache.pig.tools.pigstats.SimplePigStats - ERROR 2997: Unable to recreate exception from backed error: org.apache.pig.backend.executionengine.ExecException: ERROR 0: Scalar has more than one row in the output. 1st : (7995), 2nd :(8028)

我在做什么错?有没有更好的方法来做我想要做的事情?

+0

将示例输入和预期输出添加到您的问题将有助于更快地获得答案。 –

回答

0

我不知道什么是在UDF的问题,但你可以用纯猪结果。使用协同组的IsEmpty内置的功能。

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); 

这也许不是最快运行的实施程序,因为它使用减少副作用的加入,但是这一切都取决于卷上。

更快的方法可能是使用复制连接,它会将标记表加载到RAM中,并使用更快的Map侧连接。坏消息是你将失去未被标记的记录。

tagged_orders = join orders by (tag_id), tags by (id) using 'replicated'; 
+0

关闭,但我一直在寻找,以填补is_x场与一个int表明标签存在一个给定的顺序。我最终找到了解决问题的办法,它涉及到两个关系的左外连接,并可能有更优雅的解决方案,我愿意接受任何更好的解决方案。 –

0

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

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

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

tags = filter tags by tag == 'x';

tag_cases = foreach tags generate id, 1 as found_tag:int;

tag_cases = distinct tag_cases;

example = join orders by o_id left outer tag_cases by id;

example = foreach example generate orders::o_id as id, (tag_cases is null ? 0 : 1) as has_tag;