2012-01-12 18:52 PigLatin中Join之后访问数据的问题

http://hi.baidu.com/parrot9/item/080d77370aa1884b3075a1a3

今天在写pig处理数据的时候遇到的这样的问题:

a = LOAD 'dataA' AS (fa1, fa2);

b = LOAD 'dataB' AS (fb1, fb2);

c = JOIN a BY fa1, b BY fb1;

d = FOREACH c GENERATE a.fa1, a.fa2;

STORE d INTO 'output';

这个脚本的作用很简单,就是数据dataA有fa1, fa2两个域,dataB有fb1, fb2两个域,我想要打印出a中所有满足fa1 == b的fb1域的值的记录,所以用JOIN这么写肯定是没有问题。但是这个pig脚本运行起来会报一个错: Scalar has more than one row in the output. 完全不make sense的一个提示。后来搜了搜,才知道应该要把上面脚本中GENERATE一句的"a.fa1"改成"a::fa1"。不过为什么直接用a.fa1来引用a中的fa1值不行呢?这跟JOIN的输出结果的格式有关系。pig中可以用illustrate 命令来从输入数据中sample一些数据出来试运行,并且给出输入输出的格式。所以我们illustrate一个c,得到

---------------------------------------------| A     | fa1:bytearray     | fa2:bytearray     | ---------------------------------------------|       | 3               | 4               | |       | 3               | 4               | ------------------------------------------------------------------------------------------| B     | fb1:bytearray     | fb2:bytearray     | ---------------------------------------------|       | 3               | 6               | |       | 3               | 6               | ---------------------------------------------
---------------------------------------------------------------------------------------------| C     | A::fa1:bytearray     | A::fa2:bytearray     | B::fb1:bytearray     | B::fb2:bytearray     | ---------------------------------------------------------------------------------------------|       | 3                  | 4                  | 3                  | 6                  | |       | 3                  | 4                  | 3                  | 6                  | |       | 3                  | 4                  | 3                  | 6                  | |       | 3                  | 4                  | 3                  | 6                  | ---------------------------------------------------------------------------------------------
所以不难理解为什么要用"A::fa1"而不用"A.fa1",因为在C里面已经不存在原来A里面的结构了,只有一个名为"A::fa1"的域。同样的功能还可以用COGROUP来实现,所以上述的代码将改为e = COGROUP a BY fa1, b BY fb1; 再illustrate 一下e -------------------------------------------------------------------------------------------------------------------------------------------------| E    | group:bytearray     | A:bag{:tuple(fa1:bytearray,fa2:bytearray)}                 | B:bag{:tuple(fb1:bytearray,fb2:bytearray)}                 | -------------------------------------------------------------------------------------------------------------------------------------------------|       | 3                   | {(3, 4), (3, 4)}                                       | {(3, 6), (3, 6)}                                       | -------------------------------------------------------------------------------------------------------------------------------------------------用COGROUP命令就还保留了原来A里面的数据结构,并且在外层加一个bag。所以要打印e的结果,就要先FLATTEN(A),把bag这个数据结构展开,然后再拿FLATTEN之后的东西用 .fa1 的方式来取到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值