【问题标题】:Unable to avoid duplicate deletion in Apache Pig无法避免 Apache Pig 中的重复删除
【发布时间】:2015-07-28 11:09:38
【问题描述】:

我是 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)  

我不知道如何解决这个问题。谁能帮我解决这个问题?以及如何以简单的方式做到这一点?

【问题讨论】:

    标签: mapreduce apache-pig


    【解决方案1】:

    嗯,您的代码的第二行完全符合您的要求,它只是首先显示客户,然后显示产品。先放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,以下字段是查看该产品的所有客户:

    展平前:

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

    展平后:

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

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

    【讨论】:

    • 您好 Balduz,感谢您的回复。它工作正常,通过您的清晰解释,我很好地理解了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 1970-01-01
    相关资源
    最近更新 更多