假设我在hdfs上有以下平面文件(我们称之为key\u值):
1,1,Name,Jack
1,1,Title,Junior Accountant
1,1,Department,Finance
1,1,Supervisor,John
2,1,Title,Vice President
2,1,Name,Ron
2,1,Department,Billing
下面是我想要的输出:
(1,1,Department,Finance,Name,Jack,Supervisor,John,Title,Junior Accountant)
(2,1,Department,Billing,Name,Ron,,,Title,Vice President)
换句话说,前两列形成唯一标识符(类似于db术语中的复合键),对于该标识符的给定值,我们希望输出中有一行(即,最后两列-实际上是键值对-只要标识符相同,就压缩到同一行)。另请注意第二行中的空值,以便为唯一标识符为(2,1)时丢失的主管工件添加占位符。
为了达到这个目的,我开始整理这个Pig剧本:
data = LOAD 'key_value' USING PigStorage(',') as (i1:int, i2:int, key:chararray, value:chararray);
data_group = GROUP data by (i1, i2);
expected = FOREACH data_group {
sorted = ORDER data BY key, value;
GENERATE FLATTEN(BagToTuple(sorted));
};
dump expected;
上面的脚本提供了以下输出:
(1,1,Department,Finance,1,1,Name,Jack,1,1,Supervisor,John,1,1,Title,Junior Accountant)
(2,1,Department,Billing,2,1,Name,Ron,2,1,Title,Vice President)
请注意,缺少supervisor的空占位符不会出现在第二条记录中(这是预期的)。如果我能将这些空值放在适当的位置,那么消除冗余列(前两个列被复制多次-每个键值对一次)似乎只是另一个投影的问题。
除了使用自定义项,有没有一种方法可以通过使用内置函数在pig中实现这一点?
更新:正如winnineicklaus正确指出的,输出中的名称是多余的。因此输出可以压缩为:
(1,1,Finance,Jack,John,Junior Accountant)
(2,1,Billing,Ron,,Vice President)
1条答案
按热度按时间mum43rcc1#
首先,让我指出,如果对于大多数行,大多数列都没有填写,那么imo最好的解决方案是使用map。内置的
TOMAP
自定义项与自定义项相结合来组合Map将使您能够做到这一点。我相信有一种方法可以解决你原来的问题,通过计算所有可能的键的列表,用空值分解出来,然后扔掉非空值也存在的示例。。。但这会涉及很多mr循环,非常难看的代码,我怀疑这并不比用其他方式组织数据好。
您还可以编写一个udf来接收一包键/值对,另一包接收所有可能的键,并生成您要查找的元组。这将更加清晰和简单。