对级联不熟悉,试图找到一种基于排序/顺序获得top N元组的方法。例如,我想知道人们最常用的100个名字。
我可以在teradata sql中做类似的操作:select top 100 first_name, num_records
from
(select first_name, count(1) as num_records
from table_1
group by first_name) a
order by num_records DESC
hadoop pig
a = load 'table_1' as (first_name:chararray, last_name:chararray);
b = foreach (group a by first_name) generate group as first_name, COUNT(a) as num_records;
c = order b by num_records DESC;
d = limit c 100;
在SQL或Pig中似乎很容易做到,但是很难找到在级联中做到这一点的方法。请建议!
假设您只需要设置管道如何做到这一点:
在Cascading 2.1.6中
Pipe firstNamePipe = new GroupBy("topFirstNames", InPipe,
new Fields("first_name"),
);
firstNamePipe = new Every(firstNamePipe, new Fields("first_name"),
new Count("num_records"), Fields.All);
firstNamePipe = new GroupBy(firstNamePipe,
new Fields("first_name"),
new Fields("num_records"),
true); //where true is descending order
firstNamePipe = new Every(firstNamePipe, new Fields("first_name", "num_records")
new First(Fields.Args, 100), Fields.All)
其中InPipe是由你的传入tap形成的,该tap保存着你上面引用的元组数据。也就是说,"first_name"。"num_records"是在new Count()
被调用时创建的。
如果你有"num_records"one_answers"first_name"数据在单独的水龙头(表或文件),那么你可以设置两个管道,指向这两个Tap
源,并使用CoGroup
连接它们。
我使用的定义来自Cascading 2.1.6:
GroupBy (String groupName, Pipe pipe, Fields groupFields, Fields sortFields, boolean reverseOrder)
Count (Fields fieldDeclaration)
第一个(Fields fieldDeclaration, int firstN)
方法1使用GroupBy并根据所需的列对它们进行分组,您可以使用级联提供的二级排序,默认情况下它按升序提供它们,如果我们希望它们按降序提供它们,我们可以使用reverseorder()
获取TOP n元组或行
非常简单,只需在FILTER中使用静态变量 count,并为每个元组计数值增加1并检查它是否大于N
当count值大于N时返回true,否则返回false
这将提供前N个元组的输出
方法2
级联提供了一个唯一的输入函数,它返回firstNbuffer
见下面的链接http://docs.cascading.org/cascading/2.2/javadoc/cascading/pipe/assembly/Unique.html