use*_*239 4 hadoop latin apache-pig
我是初学者,学习猪拉丁语.需要从文件中提取记录.创建了两个文件T1和T2,一些元组对于这两个文件都是通用的,因此需要提取仅存在于T1中的元组,并且需要省略T1和T2之间的公共元组.有人可以帮帮我吗...
谢谢
首先你要看看this Venn Diagram.你想要的只是中间位.所以首先你需要对full outer JOIN数据做一个.然后,由于nulls在键不常见时在外部JOIN中创建,因此您需要过滤JOIN的结果以仅包含具有一个空的行(维恩图的非交叉部分).
这是它在猪脚本中的样子:
-- T1 and T2 are the two sets of tuples you are using, their schemas are:
-- T1: {t: (num1: int, num2: int)}
-- T2: {t: (num1: int, num2: int)}
-- Yours will be different, but the principle is the same
B = JOIN T1 BY t FULL, T2 BY t ;
C = FILTER B BY T1::t is null OR T2::t is null ;
D = FOREACH C GENERATE (T1::t is not null? T1::t : A2::t) ;
Run Code Online (Sandbox Code Playgroud)
使用此示例输入遍历步骤:
T1: T2:
(1,2) (4,5)
(3,4) (1,2)
Run Code Online (Sandbox Code Playgroud)
B 完整的外部JOIN导致:
B: {T1::t: (num1: int,num2: int),T2::t: (num1: int,num2: int)}
((1,2),(1,2))
(,(4,5))
((3.4),)
Run Code Online (Sandbox Code Playgroud)
T1是左元组,T2是正确的元组.我们必须使用它::来识别哪个t,因为它们具有相同的名称.
现在,C过滤器B以便只保留带有null的行.导致:
C: {T1::t: (num1: int,num2: int),T2::t: (num1: int,num2: int)}
(,(4,5))
((3.4),)
Run Code Online (Sandbox Code Playgroud)
这是你想要的输出,但使用起来有点乱. D使用bincond(?:)删除null.所以最终的输出将是:
D: {T1::t: (num1: int,num2: int)}
((4,5))
((3.4))
Run Code Online (Sandbox Code Playgroud)
更新:
如果您想仅保留左侧(T1)(或右侧(T2),如果您切换的话)连接侧.你可以这样做:
-- B is the same
-- We only want to keep tuples where the T2 tuple is null
C = FILTER B BY T2::t is null ;
-- Generate T1::t to get rid of the null T2::t
D = FOREACH C GENERATE T1::t ;
Run Code Online (Sandbox Code Playgroud)
然而,回顾原始的维恩图,使用完整JOIN是不必要的.如果你看一下这个different Venn Diagram,你可以看到它覆盖了你想要的集合而没有任何额外的操作.因此,您应该更改B为:
B = JOIN T1 BY t LEFT, T2 BY t ;
Run Code Online (Sandbox Code Playgroud)