首先你要看看 this Venn Diagram . 你想要的只是中间那一点。所以首先你需要做一个 full outer JOIN 在数据上。那么,自从 nulls 如果在外部联接中创建,则当键不是公共键时,您将希望过滤联接的结果,使其仅包含具有一个空值的行(维恩图的非相交部分)。 在Pig的剧本里是这样的:
-- 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) ;
-- 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 ;
然而,回顾原始的维恩图,使用一个完整的 JOIN 是不必要的。如果你看这个 different Venn Diagram ,您可以看到它覆盖了您想要的集合,而不需要任何额外的操作。因此,你应该改变 B 收件人:
T1 = load '/path/to/file1' using PigStorage() as (
f1,
f2,
f3);
T1 = foreach T1 generate
$0.., --all fields
1 as day1,
0 as day2);
T2 = load '/path/to/file2' using PigStorage() as (
f1,
f2,
f3);
T2 = foreach T2 generate
$0.., --all fields
0 as day1,
1 as day2);
T3 = union T1, T2;
-- assuming f1 is your join field
T3grouped = foreach (group T3 by f1) generate
flatten(T3),
sum(T3.day1) as day1,
sum(T3.day2) as day2;
T3result = filter T3grouped by day1==0;
这将返回在第1天没有出现的具有f1的行。相当于
T3 = T2 by f1 LEFT OUTER, T1 by f1;
T3result = filter T3 by T1::f1 is null
2条答案
按热度按时间7kqas0il1#
首先你要看看
this Venn Diagram
. 你想要的只是中间那一点。所以首先你需要做一个full outer JOIN
在数据上。那么,自从nulls
如果在外部联接中创建,则当键不是公共键时,您将希望过滤联接的结果,使其仅包含具有一个空值的行(维恩图的非相交部分)。在Pig的剧本里是这样的:
使用此示例输入完成以下步骤:
B: {T1::t: (num1: int,num2: int),T2::t: (num1: int,num2: int)}
((1,2),(1,2))
(,(4,5))
((3.4),)
```
T1
是左元组,并且T2
是正确的元组。我们必须使用::
以确定t
,因为他们有相同的名字。现在,
C
过滤器B
这样就只保留带有null的行。导致:这是您想要的输出,但使用起来有点混乱。
D
使用bincond
(the?:)删除空值。因此,最终输出将是:更新:
如果您只想保留联接的左侧(t1)(或者如果您切换了对象,则保留右侧(t2))。您可以这样做:
然而,回顾原始的维恩图,使用一个完整的
JOIN
是不必要的。如果你看这个different Venn Diagram
,您可以看到它覆盖了您想要的集合,而不需要任何额外的操作。因此,你应该改变B
收件人:monwx1rj2#
我相信有一个更有效的方法来完成它,特别是如果t1和t2非常大的话。我正在处理一个每个文件有几十亿行的数据集,我只对t2中t1中不存在的行感兴趣。两个文件具有相同的架构和相似的大小。
这将返回在第1天没有出现的具有f1的行。相当于
但要快得多。联合版本在10分钟内运行,联合版本已经运行了超过2小时(仍然没有完成)。从计数器上看,union版本生成了更多的i/o(特别是在Map器周围),但只使用了50%的cpu。