他的有关hadoop/pig/hive/hbase的其他文章:http://my.oschina.net/leejun2005/blog?catalog=186187
问题:
有如下数据文件 city.txt (id, city, value)
cat city.txt
1 wh 500
2 bj 600
3 wh 100
4 sh 400
5 wh 200
6 bj 100
7 sh 200
8 bj 300
9 sh 900
需要按 city 分组聚合,然后从每组数据中取出前两条value最大的记录。
1、这是实际业务中经常会遇到的 group TopK 问题,下面来看看 pig 如何解决:
1 | a = load '/data/city.txt' using PigStorage( ' ' ) as (id:chararray, city:chararray, value: int ); |
3 | c = foreach b {c1= order a by value desc ; c2=limit c1 2; generate group ,c2.value;}; |
4 | d = stream c through `sed 's/[(){}]//g' `; |
结果:
这几行代码其实也实现了mysql中的 group_concat 函数的功能:
1 | a = load '/data/city.txt' using PigStorage( ' ' ) as (id:chararray, city:chararray, value: int ); |
3 | c = foreach b {c1= order a by value desc ; generate group ,c1.value;}; |
4 | d = stream c through `sed 's/[(){}]//g' `; |
结果:
2、下面我们再来看看hive如何处理group topk的问题:
本质上HSQL和sql有很多相同的地方,但HSQL目前功能还有很多缺失,至少不如原生态的SQL功能强大,
比起PIG也有些差距,如果SQL中这类分组topk的问题如何解决呢?
但是这种写法在HQL中直接报语法错误了,下面我们只能用hive udf的思路来解决了:
排序city和value,然后对city计数,最后where过滤掉city列计数器大于k的行即可。
好了,上代码:
(1)定义UDF:
01 | package com.example.hive.udf; |
02 | import org.apache.hadoop.hive.ql. exec .UDF; |
04 | public final class Rank extends UDF{ |
06 | private String last_key; |
07 | public int evaluate(final String key ){ |
08 | if ( ! key .equalsIgnoreCase(this.last_key) ) { |
12 | return this.counter++; |
(2)注册jar、建表、导数据,查询:
2 | create temporary function rank as 'com.example.hive.udf.Rank' ; |
3 | create table city(id int ,cname string,value int ) row format delimited fields terminated by ' ' ; |
4 | LOAD DATA LOCAL INPATH 'city.txt' OVERWRITE INTO TABLE city; |
5 | select cname, value from ( |
6 | select cname,rank(cname) csum,value from ( |
7 | select id, cname, value from city distribute by cname sort by cname,value desc |
(3)结果:
可以看到,hive相比pig来说,处理起来稍微复杂了点,但随着hive的日渐完善,以后比pig更简洁也说不定。
REF:hive中分组取前N个值的实现
http://baiyunl.iteye.com/blog/1466343
PS:
如果说hive类似sql的话,那pig就类似plsql存储过程了:程序编写更自由,逻辑能处理的更强大了。
pig中还能直接通过反射调用java的静态类中的方法,这块内容请参考之前的相关pig博文。
附几个HIVE UDAF链接,有兴趣的同学自己看下:
Hive UDAF和UDTF实现group by后获取top值 http://blog.csdn.net/liuzhoulong/article/details/7789183
hive中自定义函数(UDAF)实现多行字符串拼接为一行 http://blog.sina.com.cn/s/blog_6ff05a2c0100tjw4.html
编写Hive UDAF http://www.fuzhijie.me/?p=118
Hive UDAF开发 http://richiehu.blog.51cto.com/2093113/386113