• 问题描述

需要连接的表如下:其中左边是child,右边是parent,我们要做的是找出grandchild和grandparent的对应关系,为此需要进行表的连接。


Tom Lucy
Tom Jim
Lucy David
Lucy Lili
Jim Lilei
Jim SuSan
Lily Green
Lily Bians
Green Well
Green MillShell
Havid James
James LiT
Richard Cheng
Cheng LiHua
 
  • 思路分析
  诚然,在写MR程序的时候要结合MR数据处理的一些特性。例如如果我们用默认的TextInputFormat来处理传入的文件数据,传入的格式是key为行号,value为这一行的值(如上例中的第一行,key为0,value为[Tom,Lucy]),在shuffle过程中,我们的值如果有相同的key,会merge到一起(这一点很重要!)。我们利用shuffle阶段的特性,merge到一组的数据够成一组关系,然后我们在这组关系中想办法区分晚辈和长辈,最后对merge里的value一一作处理,分离出grandchild和grandparent的关系。
       例如,Tom Lucy传入处理后我们将其反转,成为Lucy Tom输出。当然,输出的时候,为了达到join的效果,我们要输出两份,因为join要两个表,一个表为L1:child parent,一个表为L2:child parent,为了达到关联的目的和利用shuffle阶段的特性,我们需要将L1反转,把parent放在前面,这样L1表中的parent和L2表中的child如果字段是相同的那么在shuffle阶段就能merge到一起。还有,为了区分merge到一起后如何区分child和parent,我们把L1表中反转后的child(未来的 grandchild)字段后面加一个1,L2表中parent(未来的grandparent)字段后加2。
 package com.test.join;

 import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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; public class STJoin { public static class STJoinMapper extends Mapper<Object, Text, Text, Text>{ @Override
protected void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
String[] rela = value.toString().trim().split(" ",2);
if(rela.length!=2)
return;
String child = rela[0];
String parent = rela[1];
context.write(new Text(parent), new Text((child+"1")));
context.write(new Text(child), new Text((parent+"2"))); } }
public static class STJoinReducer extends Reducer<Text, Text, Text, Text>{ @Override
protected void reduce(Text arg0, Iterable<Text> arg1,Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
ArrayList<String> grandParent = new ArrayList<>();
ArrayList<String> grandChild = new ArrayList<>();
Iterator<Text> iterator = arg1.iterator();
while(iterator.hasNext()){
String text = iterator.next().toString();
if(text.endsWith("1"))
grandChild.add(text.substring(0, text.length()-1));
if(text.endsWith("2"))
grandParent.add(text.substring(0, text.length()-1));
} for(String grandparent:grandParent){
for(String grandchild:grandChild){
context.write(new Text(grandchild), new Text(grandparent));
}
}
}
} public static void main(String args[]) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = new Job(conf,"STJoin");
job.setMapperClass(STJoinMapper.class);
job.setReducerClass(STJoinReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, new Path("hdfs://localhost:9000/user/hadoop/STJoin/joinFile"));
FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/user/hadoop/STJoin/joinResult")); System.exit(job.waitForCompletion(true)?0:1);
}
}
  • 结果显示

 

Richard    LiHua
Lily Well
Lily MillShell
Havid LiT
Tom Lilei
Tom SuSan
Tom Lili
Tom David

以上代码在hadoop1.0.3平台实现

【原创】MapReduce编程系列之表连接的更多相关文章

  1. Hadoop阅读笔记(三)——深入MapReduce排序和单表连接

    继上篇了解了使用MapReduce计算平均数以及去重后,我们再来一探MapReduce在排序以及单表关联上的处理方法.在MapReduce系列的第一篇就有说过,MapReduce不仅是一种分布式的计算 ...

  2. 【SqlServer系列】表连接

    1   概述 1.1  已发布[SqlServer系列]文章 [SqlServer系列]MYSQL安装教程 [SqlServer系列]数据库三大范式 [SqlServer系列]表单查询 1.2  本篇 ...

  3. MapReduce编程系列 — 5:单表关联

    1.项目名称: 2.项目数据: chile    parentTom    LucyTom    JackJone    LucyJone    JackLucy    MaryLucy    Ben ...

  4. 【原创】MapReduce编程系列之二元排序

    普通排序实现 普通排序的实现利用了按姓名的排序,调用了默认的对key的HashPartition函数来实现数据的分组.partition操作之后写入磁盘时会对数据进行排序操作(对一个分区内的数据作排序 ...

  5. MapReduce编程系列 — 6:多表关联

    1.项目名称: 2.程序代码: 版本一(详细版): package com.mtjoin; import java.io.IOException; import java.util.Iterator; ...

  6. MapReduce编程系列 — 4:排序

    1.项目名称: 2.程序代码: package com.sort; import java.io.IOException; import org.apache.hadoop.conf.Configur ...

  7. MapReduce编程系列 — 3:数据去重

    1.项目名称: 2.程序代码: package com.dedup; import java.io.IOException; import org.apache.hadoop.conf.Configu ...

  8. MapReduce编程系列 — 2:计算平均分

    1.项目名称: 2.程序代码: package com.averagescorecount; import java.io.IOException; import java.util.Iterator ...

  9. MapReduce编程系列 — 1:计算单词

    1.代码: package com.mrdemo; import java.io.IOException; import java.util.StringTokenizer; import org.a ...

随机推荐

  1. 学会Twitter Bootstrap不再难

    Twitter Bootstrap 3.0 是对其过去的重大改变,现在它更偏向于移动应用的框架,并且宣称是最好的web设计css框架之一,的确如此. 可能有人曾经使用过Twitter Bootstra ...

  2. hdu 1251 统计难题 trie入门

    统计难题 Problem Description Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本 ...

  3. 加解密算法二:非对称加解密及RSA算法的实现

    加密和解密使用不同的密钥的一类加密算法.这类加密算法通常有两个密钥A和B,使用密钥A加密数据得到的密文,只有密钥B可以进行解密操作(即使密钥A也无法解密):相反,使用密钥B加密数据得到的密文,只有密钥 ...

  4. 扩展pl0编译器设计——总述

    所谓编译器,实际上就是我们编程时将输入的高级语言代码转换成相应的目标代码,从而实现将目标代码转换成汇编码的一种过渡工具. 这种工具根据具体情况不同,可以将不同的高级语言代码转换成不同的目标代码,例如将 ...

  5. php-- 避免表单的重复提交

    用户提交表单时可能因为网速的原因,或者网页被恶意刷新,致使同一条记录重复插入到数据库中,这是一个比较棘手的问题.我们可以从客户端和服务器端一起着手,设法避免同一表单的重复提交. 1.使用客户端脚本 提 ...

  6. PYTHON多进程样码

    敲了一晚上,留个念想. 发现它和LINUX的C编程差不多,就是作了PYTHON化的语法封装. 以后希望有机会能用上.. A,多进程函数化实现 import multiprocessing import ...

  7. android fragment嵌套fragment出现的问题:no activity

    package com.example.fragmentNavigation2.fragment; import android.content.Context; import android.os. ...

  8. Mysql的列索引和多列索引(联合索引)

    转自:http://blog.chinaunix.net/uid-29305839-id-4257512.html 创建一个多列索引:CREATE TABLE test (      id       ...

  9. Tomcat 6 支持 NIO -- Tomcat的四种基于HTTP协议的Connector性能比较(转载)

    Tomcat从5.5版本开始,支持以下四种Connector的配置分别为: <Connector port="8081" protocol="org.apache. ...

  10. MSSql2008打开企业管理器出错,具体显示提示无法识别的配置节 system.serviceModel。

    MSSql2008打开企业管理器出错详细信息: 标题: 已注册的服务器 ------------------------------   无法读取此系统上以前注册的服务器的列表.请在“已注册的服务器” ...