无法避免Apache Pig中的重复删除

时间:2015-07-28 11:09:38

标签: mapreduce apache-pig

我是Apache Pig的新手。我想将以下输入拆分并展平到我所需的输出中,就像谁都看过那个产品一样。

我的输入:(UserId,ProductId)

12345   123456,23456,987653  
23456   23456,123456,234567  
34567   234567,765678,987653

我的必需输出:(ProductId,UserId)

123456  12345  
123456  23456  
23456   12345    
23456   23456  
987653  12345  
987653  34567  
234567  23456  
234567  34567  
765678  34567

我的猪脚本:

 a = load '/home/hadoopuser/ips' using PigStorage('\t') as (key:chararray, val:chararray);  
 b = foreach a generate key as ky1, FLATTEN(TOKENIZE(val)) as vl1;  
 c = group b by vl1;  
 d = foreach c generate group as vl2, $1 as ky2;  
 e = foreach d generate vl2, BagToString(ky2) as kyy;  
 f = foreach e generate vl2 as vl3,FLATTEN(STRSPLIT(kyy,'_')) as ky3;  
 g = foreach f generate vl3, FLATTEN(TOKENIZE(ky3)) as kk1; 
 dump g; 

我得到了以下输出,它消除了重复(重复)值,

(23456,12345)  
(123456,12345)  
(234567,23456)  
(765678,34567)  
(987653,12345)  

我不知道如何解决这个问题。任何人都可以帮我解决这个问题吗?以及如何以简单的方式做到这一点?

1 个答案:

答案 0 :(得分:0)

嗯,代码的第二行完全符合您的要求,它只是首先显示客户,然后显示产品。首先是FLATTEN,然后是key部分:

a = load '/home/hadoopuser/ips' using PigStorage('\t') as (key:chararray, val:chararray);  
b = foreach a generate FLATTEN(TOKENIZE(val)) as ProductId, key as UserId;
dump b; 

(123456,12345)
(23456,12345)
(987653,12345)
(23456,23456)
(123456,23456)
(234567,23456)
(234567,34567)
(765678,34567)
(987653,34567)

至于为什么每个ProductId仅使用当前代码获得一个结果,您将按ProductId进行分组,每个不同的ProductId为您提供一行,其中包含查看该产品的所有客户。然后,您将该包转换为由_分隔的巨大字符串,将其再次转换为与之前相同的包:

d = foreach c generate group as vl2, $1 as ky2;  
e = foreach d generate vl2, BagToString(ky2) as kyy;  
f = foreach e generate vl2 as vl3,FLATTEN(STRSPLIT(kyy,'_')) as ky3;  

BagToString UDF将包转换为字符串,将包中的不同值连接在一个自定义分隔符之间,默认为_。但是,在下一行中,您将其分割为_,从而产生与之前相同的包。但是,您FLATTEN那个包,所以现在不是一行包含ProductId和一个包,而是有一行包含多个字段,第一个是ProductId,以下是所有查看产品的客户的字段:

在FLATTEN之前:

(23456,{(23456,23456),(12345,23456)})
(123456,{(23456,123456),(12345,123456)})
(234567,{(34567,234567),(23456,234567)})
(765678,{(34567,765678)})
(987653,{(34567,987653),(12345,987653)})

FLATTEN之后:

(23456,23456,23456,12345,23456)
(123456,23456,123456,12345,123456)
(234567,34567,234567,23456,234567)
(765678,34567,765678)
(987653,34567,987653,12345,987653)

这就是错误。每个产品只有一行,每个客户每行有几个字段。在应用最后一个foreach时,选择第一个字段(产品)和第二个字段(所有客户中的第一个),丢弃每行上的其余客户。