我最近在工作中遇到这个问题,是关于Pig扁的。我用一个简单的例子来表达
两个文件
===文件1===
1个
2个
4天
===文件2(制表符分隔)===
1安培
2个b
3摄氏度
Pig剧本一:
a = load 'file1' as (str:chararray);
b = load 'file2' as (num:int, ch:chararray);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2)) as (num:int, ch:chararray);
c = join a1 by num, b by num;
dump c; -- exception java.lang.String cannot be cast to java.lang.Integer
Pig剧本二:
a = load 'file1' as (str:chararray);
b = load 'file2' as (num:int, ch:chararray);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2)) as (num:int, ch:chararray);
a2 = foreach a1 generate (int)num as num, ch as ch;
c = join a2 by num, b by num;
dump c; -- exception java.lang.String cannot be cast to java.lang.Integer
Pig脚本3:
a = load 'file1' as (str:chararray);
b = load 'file2' as (num:int, ch:chararray);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2));
a2 = foreach a1 generate (int)$0 as num, $1 as ch;
c = join a2 by num, b by num;
dump c; -- right
我不知道为什么脚本1,2是错的,脚本3是对的,我还想知道有没有更简洁的表达式来得到关系c,thx。
1条答案
按热度按时间yzuktlbb1#
您不使用pigstorage有什么特别的原因吗?因为它可以让你的生活变得更轻松:)。
还要注意的是,在file1中,您使用下划线作为分隔符,但将“-”作为strsplit的参数。
编辑:我花了更多的时间在你提供的脚本上;脚本1和脚本2确实不起作用,脚本3也是这样工作的(没有额外的foreach):
至于问题的根源,我会大胆猜测,可能与此有关(如pig文档中所述),并与pig的运行周期优化相结合:
如果将具有空内部模式的包展平,则结果关系的模式为空。
在您的例子中,我相信strsplit结果的模式在运行时之前是未知的。
edit2:好的,这是我的理论解释:
这是脚本2和脚本3的完整解释输出。我就把有趣的部分贴在这里。
以上部分是脚本2;请看最后一行。它假定输出
flatten(STRSPLIT)
将有类型的第一个元素integer
(因为您以这种方式提供了架构)。但事实上STRSPLIT
有一个null
被视为bytearray
领域;so输出flatten(STRSPLIT)
实际上是(n:bytearray, c:bytearray)
. 因为您提供了一个模式,pig尝试对a1
)至num
字段;失败的原因是num
实际上是javaString
表示为tearray。由于这个java转换失败,pig甚至不尝试在上面的行中进行显式转换。让我们看看脚本3的情况:
看最后一行,这里是输出
a1
被恰当地视为bytearray
,这里没有问题。现在看看倒数第二行;pig尝试(并成功)从bytearray
至integer
.