在Pig Latin中提取文件之间的不匹配记录

时间:2013-07-31 18:31:04

标签: hadoop apache-pig latin

我是初学者,学习猪拉丁语。需要从文件中提取记录。创建了两个文件T1和T2,一些元组对于这两个文件是通用的,因此需要提取仅存在于T1中的元组,并且需要省略T1和amp之间的公共元组。 T2。有人可以帮助我......

由于

2 个答案:

答案 0 :(得分:7)

首先,您需要查看this Venn Diagram。你想要的只是中间位。首先,您需要对数据执行full outer JOIN。然后,由于当键不常见时在外部JOIN中创建nulls,您将希望过滤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) ;

使用此示例输入执行步骤:

T1:      T2:
(1,2)    (4,5)
(3,4)    (1,2)

B完整的外部JOIN导致:

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,因此只保留带有空值的行。导致:

C: {T1::t: (num1: int,num2: int),T2::t: (num1: int,num2: int)}
(,(4,5))
((3.4),)

这是你想要的输出,但使用起来有点乱。 D使用bincond(?:)删除null。所以最终的输出将是:

D: {T1::t: (num1: int,num2: int)}
((4,5))
((3.4))

<强>更新
如果你想只保留左边(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 ;

然而,回顾原始的维恩图,使用完整的JOIN是不必要的。如果您查看此different Venn Diagram,您可以看到这涵盖了您想要的集合而无需任何额外操作。因此,您应将B更改为:

B = JOIN T1 BY t LEFT, T2 BY t ;

答案 1 :(得分:1)

我相信有一种更有效的方法可以完成它,特别是如果T1和T2非常大。 我正在处理每个文件有几十亿行的数据集,而我只对T2中不存在的T2行感兴趣。两个文件都具有相同的模式,并且大小相似。

listView.setAdapter(adapter);
listView.setVisibility(View.VISIBLE);

这将返回具有f1&#39s的行,这些行在第1天没有出现。它相当于

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;

但要快得多。 UNION版本运行约10分钟,JOIN版本已运行> 2小时(仍未完成)。查看计数器,UNION版本会生成更多I / O(特别是在映射器周围),但只占CPU的50%。