使用 TOBAG 内置函数来构建您的包:
$ cat input
TRAABRX12903CC4816,1548880,2:19,4:7
TRAABRX12903CC4816,1548881,2:19,4:7,5:23,7:3
TRAABRX12903CC4816,1548882
TRAABRX12903CC4816,1548883,17:33
$ cat test.pig
data = LOAD 'input' USING PigStorage(',');
data0 = FOREACH data GENERATE $0 AS key:chararray, $1 AS key2:chararray, TOBAG($2 ..) AS bow:{(pair)};
DESCRIBE data0;
DUMP data0;
$ pig -x local test.pig
...
data0: {key: chararray,key2: chararray,bow: {(pair: NULL)}}
...
(TRAABRX12903CC4816,1548880,{(2:19),(4:7)})
(TRAABRX12903CC4816,1548881,{(2:19),(4:7),(5:23),(7:3)})
(TRAABRX12903CC4816,1548882,{})
(TRAABRX12903CC4816,1548883,{(17:33)})
但是,如果您想拆分 id:cnt 对,这将变得更加棘手。因为没有办法将模式分配给任意数量的元素,并且TOBAG
是 UDF,Pig 不能将 bytearray 转换为 chararray 或以后的任何其他内容。
我建议将整行加载为字符串 ( USING PigStorage('\n')
),使用STRSPLIT
限制为 3 来获取您的key
,key2
和逗号分隔的字符串列表,然后STRSPLIT
在逗号和冒号上迭代以获得您想要的对,使用FLATTEN
和TOBAG
如所须。我会为你演示这一点,但我被困在 Pig 0.9 上,根据PIG-2311判断,这在 Pig 0.10 之前是不可能的。
最简单的解决方案可能就是编写自己的 UDF 来解释如下字符串2:13,9:4,5:4
:
data = LOAD 'input' USING PigStorage('\n') AS (line:chararray);
data0 = FOREACH data GENERATE FLATTEN(STRSPLIT(line, ',', 3)) AS (key:chararray, key2:chararray, pairs:chararray);
data1 = FOREACH data0 GENERATE key, key2, myudfs.PARSE_PAIRS(pairs);
wheremyudfs.PARSE_PAIRS
返回一个包含你想要的元组的包。祝你好运。