假设我有一个如下所示的输入文件input.dat
:
apples 10
oranges 30
apples 6
pears 5
现在,当我加载,分组和投影数据时:
sources = LOAD 'input.dat' as { a:chararray, b:int };
grouped = GROUP sources BY a;
projection = foreach sources generate flatten(group), SUM(sources.b);
dump projection;
我得到以下内容:
apples 16
oranges 30
pears 5
现在,我想将SUM(sources.b)
低于某个阈值的数据“重新分组”为一行。例如,如果阈值为20,我会得到:
other 21
oranges 30
因为“苹果”和“梨”的总和低于20的阈值。
在我看来,我可以采用几种不同的方法:
SPLIT
上的grouped
运算符创建两个关系:above_threshold
和below_threshold
。然后投影below_threshold
以将a
的值替换为“other”并重新组合。最后UNION
与above_threshold
一起生成,然后再次进行最终投影。projection
时,有条件地生成a
(基于SUM(sources.b)
),然后重新组projection
(将所有内容分组)将“其他”行组合在一起),然后再次投影(以展平重新分组的数据)。上述方法之一明显优于其他方法吗?或者是否有另一种方法更有效或更容易维护?
答案 0 :(得分:1)
选项1更好。这是因为选项1只需要将below_threshold
数据传递到M / R记录计数中;而在选项2中,您正在重新组合所有内容,似乎就是这样。
此外,方法1有一些好处,最值得注意的是:
below_threshold
计数会非常快,因为你只需要1个reducer,而且只需要一个键即可组合奇迹。UNION
。您可以输出到两个位置,然后通过将它们视为猪外部的相同输出来“联合”。例如,您仍然可以hadoop fs -getmerge my_out/*/part-r-* output
来获取两个输出。 所以,我看到你的Pig脚本看起来像:
sources = LOAD 'input.dat' as { a:chararray, b:int };
grouped = GROUP sources BY a;
projection = foreach sources generate flatten(group) as n, SUM(sources.b) as s;
SPLIT projection into above_threshold if s >= 20, below_threshold if s < 20;
dump above_threshold;
below_grouped = GROUP below_threshold BY 'other' PARALLEL 1;
below_projection = FOREACH below_grouped GENERATE group, SUM(below_threshold.s);
dump below_projection;