MapReduce聚合

mapreduce的核心思想就是:map读入一条记录,然后重置其key 、value;reduce针对map的同一条key,把其values整合,然后重新输出key、value;

这两天做mapreduce时,忽然有种想法:针对一行记录,是否有输出多行记录,包含有不同到key,value,的情况;这种情况到应用是否有好处呢?

假设有这样的一个数据:其中第一列代表用户的标识,第二列代表书籍的标识

1,A
1,B
1,C
2,A
2,B
3,B
3,C
4,A
4,E
5,C
5,E

问题是:要输出两个集合,分别是:针对用户1,输出看过A书的其他用户的集合,以及其他用户看过的其他书籍,比如:

1,A---》2,4;E,B

1,B---》3,2;A,C

。。。

那现在看下,我们可以如何操作呢?很直观的两种想法:一,以用户标识作为key,书籍标识作为value,那么经过mapreduce后,我们得到到数据如下:

1---》A,B,C

2---》A,B

。。。

或者以书籍标识作为key ,以用户标识作为value,那么我们得到的数据如下:

A--》1,2,4

B--》1,2,3

.。。

这两种情况都很难做到我们要的输出,那么如何做呢?就用文章开始说过的方法:一条记录产生多条key/value:

下面就具体代码进行分析:

第一个Mapper:

package org.fansy.data907;

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
/*
 * first map input: 1,A
 * 1,A
 * 1,B
 * reduce output: 1 /t A,B,C,
 */
public class BookM extends Mapper<LongWritable,Text,Text,Text>{
	public void map(LongWritable key,Text line,Context context)throws IOException,InterruptedException{
		String[] values=line.toString().split(",");
		if(values.length!=2){
			return;
		}
		String userid=values[0];
		String bookid=values[1];
		context.write(new Text(userid), new Text(bookid));
	}
}

第一个Reducer:

package org.fansy.data907;

import java.io.IOException;


import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class BookR extends Reducer<Text,Text,Text,Text>{
	public void reduce(Text key,Iterable<Text> values,Context context)throws IOException,
		InterruptedException{
		StringBuffer sb=new StringBuffer();
		for(Text val:values){
			sb.append(val.toString());
			sb.append(",");
		}
		context.write(key, new Text(sb.toString()));
	}

}
第一个M/R的操作是输出用户标识和其所看过的所有书籍,这个和第一种操作一样,输出如下&#x
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值