需求:有如下数据,求出每一个订单id中成交金额最大的三笔交易(字段分别为:订单id,用户id,商品名称,单价,数量),即分组求TOP-N。
order001,u001,小米6,1999.9,2 order001,u001,雀巢咖啡,99.0,2 order001,u001,安慕希,250.0,2 order001,u001,经典红双喜,200.0,4 order001,u001,防水电脑包,400.0,2 order002,u002,小米手环,199.0,3 order002,u002,榴莲,15.0,10 order002,u002,苹果,4.5,20 order002,u002,肥皂,10.0,40 |
实现思路:
实现思路:
map: 读取数据切分字段(用逗号切分),封装数据到一个OrderBean对象中作为key传输,key要按照成交金额比大小
reduce:利用自定义GroupingComparator将数据按订单id进行分组,然后在reduce方法中输出每组数据的前N条即可
(1)首先需要保证的是让orderid相同的数据发送给相同的reduce task,如果同一个订单没有发送到同一个reduce task,那么排序为局部排序,没有意义。为了完成此目的,需要继承Partitioner类自定义一个OrderIdPartitioner类。(未自定义前是按照key的哈希值进行分区,本例中key为OrderBean对象,不同对象的哈希值肯定不同)。我们需要做的是按照OrderBean对象的orderid分区。
OrderIdPartitioner类代码如下:
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Partitioner;
public class OrderIdPartitioner extends Partitioner<OrderBean, NullWri