无法避免在 Apache Pig 中重复删除
Unable to avoid duplicate deletion in 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
我的 Pig 脚本:
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, 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)
我不知道如何解决这个问题。谁能帮我解决这个问题?以及如何以简单的方式做到这一点?
好吧,您的代码的第二行完全符合您的要求,它只是首先显示客户,其次显示产品。先放 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, 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
时,您 select 第一个字段(产品)和第二个字段(所有客户中的第一个),丢弃每一行的其余客户。
我是 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
我的 Pig 脚本:
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, 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)
我不知道如何解决这个问题。谁能帮我解决这个问题?以及如何以简单的方式做到这一点?
好吧,您的代码的第二行完全符合您的要求,它只是首先显示客户,其次显示产品。先放 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, 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
时,您 select 第一个字段(产品)和第二个字段(所有客户中的第一个),丢弃每一行的其余客户。