pig拉丁语中flatten算子的java模式

5w9g7ksd  于 2021-06-24  发布在  Pig
关注(0)|答案(1)|浏览(375)

我最近在工作中遇到这个问题,是关于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。

yzuktlbb

yzuktlbb1#

您不使用pigstorage有什么特别的原因吗?因为它可以让你的生活变得更轻松:)。

a = load '/file1' USING PigStorage('_') AS (num:int, char:chararray);
b = load '/file2' USING PigStorage('\t') AS (num:int, char:chararray);
c = join a by num, b by num;
dump c;

还要注意的是,在file1中,您使用下划线作为分隔符,但将“-”作为strsplit的参数。
编辑:我花了更多的时间在你提供的脚本上;脚本1和脚本2确实不起作用,脚本3也是这样工作的(没有额外的foreach):

a = load 'file1' as (str:chararry);
b = load 'file2' as (num:int, ch:chararry);
a1 = foreach a generate flatten(STRSPLIT(str,'_',2));
c = join a1 by (int)($0), b by num;
dump c;

至于问题的根源,我会大胆猜测,可能与此有关(如pig文档中所述),并与pig的运行周期优化相结合:
如果将具有空内部模式的包展平,则结果关系的模式为空。
在您的例子中,我相信strsplit结果的模式在运行时之前是未知的。
edit2:好的,这是我的理论解释:
这是脚本2和脚本3的完整解释输出。我就把有趣的部分贴在这里。

|---a2: (Name: LOForEach Schema: num#288:int,ch#289:chararray)
|   |   |
|   |   (Name: LOGenerate[false,false] Schema: num#288:int,ch#289:chararray)ColumnPrune:InputUids=[288, 289]ColumnPrune:OutputUids=[288, 289]
|   |   |   |
|   |   |   (Name: Cast Type: int Uid: 288)
|   |   |   |
|   |   |   |---num:(Name: Project Type: int Uid: 288 Input: 0 Column: (*))

以上部分是脚本2;请看最后一行。它假定输出 flatten(STRSPLIT) 将有类型的第一个元素 integer (因为您以这种方式提供了架构)。但事实上 STRSPLIT 有一个 null 被视为 bytearray 领域;so输出 flatten(STRSPLIT) 实际上是 (n:bytearray, c:bytearray) . 因为您提供了一个模式,pig尝试对 a1 )至 num 字段;失败的原因是 num 实际上是java String 表示为tearray。由于这个java转换失败,pig甚至不尝试在上面的行中进行显式转换。
让我们看看脚本3的情况:

|---a2: (Name: LOForEach Schema: num#85:int,ch#87:bytearray)
|   |   |
|   |   (Name: LOGenerate[false,false] Schema: num#85:int,ch#87:bytearray)ColumnPrune:InputUids=[]ColumnPrune:OutputUids=[85, 87]
|   |   |   |
|   |   |   (Name: Cast Type: int Uid: 85)
|   |   |   |
|   |   |   |---(Name: Project Type: bytearray Uid: 85 Input: 0 Column: (*))

看最后一行,这里是输出 a1 被恰当地视为 bytearray ,这里没有问题。现在看看倒数第二行;pig尝试(并成功)从 bytearrayinteger .

相关问题