hadoop 单表关联

恩,说真的,原来的那篇文章对于这个单表处理有点搞复杂了。

4、单表关联

    前面的实例都是在数据上进行一些简单的处理,为进一步的操作打基础。"单表关联"这个实例要求给出的数据寻找关心的数据,它是对原始数据所包含信息的挖掘。下面进入这个实例。

4.1 实例描述

    实例中给出child-parent(孩子——父母)表,要求输出grandchild-grandparent(孙子——爷奶)表。

    样例输入如下所示。

  file:

 

 

Tom        Lucy

Tom        Jack

Jone        Lucy

Jone        Jack

Lucy        Mary

Lucy        Ben

Jack        Alice

Jack        Jesse

Terry        Alice

Terry        Jesse

Philip        Terry

Philip        Alma

Mark        Terry

Mark        Alma

 

 

 

    家族树状关系谱:

 

 

 

 image

 

图4.2-1 家族谱

 

    样例输出如下所示。

 

    file:

 

 

 

Tom              Alice

Tom              Jesse

Jone              Alice

Jone              Jesse

Tom              Mary

Tom              Ben

Jone              Mary

Jone              Ben

Philip              Alice

Philip              Jesse

Mark              Alice

Mark              Jesse

 

 

 

4.2 设计思路

 

       分析这个实例,显然需要进行单表连接,连接的是左表parent列和右表child列,且左表右表同一个表

 

  连接结果除去连接的两列就是所需要的结果——"grandchild--grandparent"表。要用MapReduce解决这个实例,首先应该考虑如何实现自连接其次就是连接列设置最后结果整理

 

      考虑到MapReduce的shuffle过程会将相同的key会连接在一起,所以可以将map结果的key设置成待连接,然后列中相同的值就自然会连接在一起了。再与最开始的分析联系起来:

 

  要连接的是左表的parent列和右表的child列,且左表和右表是同一个表,所以在map阶段读入数据分割childparent之后,会将parent设置成keychild设置成value进行输出,并作为左表;再将同一对childparent中的child设置成keyparent设置成value进行输出,作为右表。为了区分输出中的左右表,需要在输出的value加上左右表信息,比如在value的String最开始处加上字符1表示左表,加上字符2表示右表。这样在map的结果中就形成了左表和右表,然后在shuffle过程中完成连接。reduce接收到连接的结果,其中每个key的value-list就包含了"1grandchild,2grandparent"关系。取出每个key的value-list进行解析,将左表中的child放入一个数组右表中的parent放入一个数组,然后对两个数组求笛卡尔积就是最后的结果了。

 

4.3 程序代码

 

    程序代码如下所示。(自己写的,原来的过于麻烦,木有看啊)

 

  

package test;

import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class STjoin {

	public static class Map extends Mapper<LongWritable, Text, Text, Text>{
		private static Text child = new Text();
		private static Text parent = new Text();
		private static Text tempChild = new Text();
		private static Text tempParent = new Text();
		
		protected void map(LongWritable key, Text value, Context context) 
				throws java.io.IOException ,InterruptedException {
			String[] splits = value.toString().split("\\s+");
			if(splits.length != 2){
				return;
			}
			child.set(splits[0]);
			parent.set(splits[1]);
			tempChild.set("1"+splits[0]);
			tempParent.set("2"+splits[1]);
			context.write(parent, tempChild);
			context.write(child, tempParent);
		};
	}
	public static class Reduce extends Reducer<Text, Text, Text, Text>{
		private static Text child = new Text();
		private static Text grand = new Text();
		private static List<String> childs = new ArrayList<String>();
		private static List<String> grands = new ArrayList<String>();
		
		protected void reduce(Text key, Iterable<Text> values, Context context) 
				throws java.io.IOException ,InterruptedException {
			// 1child 2 grand
			for (Text value : values) {
				String temp = value.toString();
				if (temp.startsWith("1"))
					childs.add(temp.substring(1));
				else
					grands.add(temp.substring(1));
			}
			//笛卡尔积
			for (String c : childs) {
				for(String g : grands){
					child.set(c);
					grand.set(g);
					context.write(child, grand);
				}
			}
			//清理
			childs.clear();
			grands.clear();
		};
	}
	
	public static void main(String[] args) throws Exception {
		Configuration conf = new Configuration();
		String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
		if(otherArgs.length != 2){
			System.err.println("Usage:STjoin");
			System.exit(2);
		}
		Job job = new Job(conf, "STjoin");
		job.setJarByClass(STjoin.class);
		
		job.setMapperClass(Map.class);
		job.setReducerClass(Reduce.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(Text.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);
		
		FileInputFormat.addInputPath(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		System.exit(job.waitForCompletion(true) ? 0 : 1);
	}
}

 

 4.4 准备测试数据,编辑文件上传到hdfs上,设置myeclipse允许参数,运行。

4.5 得到结果。


Tom     Alice
Tom     Jesse
Jone    Alice
Jone    Jesse
Tom     Mary
Tom     Ben
Jone    Mary
Jone    Ben
Philip  Alice
Philip  Jesse
Mark    Alice
Mark    Jesse

 

 

 

posted @ 2014-06-17 22:38  jseven  阅读(1055)  评论(0编辑  收藏  举报