Home > Database > Mysql Tutorial > body text

hadoop实例---多表关联

WBOY
Release: 2016-06-07 16:31:22
Original
1106 people have browsed it

多表关联和单表关联类似,它也是通过对原始数据进行一定的处理,从其中挖掘出关心的信息。如下 输入的是两个文件,一个代表工厂表,包含工厂名列和地址编号列;另一个代表地址表,包含地址名列和地址编号列。要求从输入数据中找出工厂名和地址名的对应关系,

多表关联和单表关联类似,它也是通过对原始数据进行一定的处理,从其中挖掘出关心的信息。如下

输入的是两个文件,一个代表工厂表,包含工厂名列和地址编号列;另一个代表地址表,包含地址名列和地址编号列。要求从输入数据中找出工厂名和地址名的对应关系,输出工厂名-地址名表

样本如下:

factory:

factoryname addressed
Beijing Red Star 1
Shenzhen Thunder 3
Guangzhou Honda 2
Beijing Rising 1
Guangzhou Development Bank 2
Tencent 3
Back of Beijing 1
Copy after login

address:

addressID addressname
1 Beijing
2 Guangzhou
3 Shenzhen
4 Xian
Copy after login


结果:

factoryname     addressname
Beijing Red Star        Beijing
Beijing Rising  Beijing
Bank of Beijing         Beijing
Guangzhou Honda         Guangzhou
Guangzhou Development Bank      Guangzhou
Shenzhen Thunder        Shenzhen
Tencent         Shenzhen
Copy after login


代码如下:

import java.io.IOException;
import java.util.*;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 MTjoin {
    public static int time = 0;
    /*
     * 在map中先区分输入行属于左表还是右表,然后对两列值进行分割,
     * 保存连接列在key值,剩余列和左右表标志在value中,最后输出
     */
    public static class Map extends Mapper {
        // 实现map函数
        public void map(Object key, Text value, Context context)
                throws IOException, InterruptedException {
            String line = value.toString();// 每行文件
            String relationtype = new String();// 左右表标识
            // 输入文件首行,不处理
            if (line.contains("factoryname") == true
                    || line.contains("addressed") == true) {
                return;
            }
            // 输入的一行预处理文本
            StringTokenizer itr = new StringTokenizer(line);
            String mapkey = new String();
            String mapvalue = new String();
            int i = 0;
            while (itr.hasMoreTokens()) {
                // 先读取一个单词
                String token = itr.nextToken();
                // 判断该地址ID就把存到"values[0]"
                if (token.charAt(0) >= '0' && token.charAt(0)  0) {
                        relationtype = "1";
                    } else {
                        relationtype = "2";
                    }
                    continue;
                }
                // 存工厂名
                mapvalue += token + " ";
                i++;
            }
            // 输出左右表
            context.write(new Text(mapkey), new Text(relationtype + "+"+ mapvalue));
        }
    }
    /*
     * reduce解析map输出,将value中数据按照左右表分别保存,
  * 然后求出笛卡尔积,并输出。
     */
    public static class Reduce extends Reducer {
        // 实现reduce函数
        public void reduce(Text key, Iterable values, Context context)
                throws IOException, InterruptedException {
            // 输出表头
            if (0 == time) {
                context.write(new Text("factoryname"), new Text("addressname"));
                time++;
            }
            int factorynum = 0;
            String[] factory = new String[10];
            int addressnum = 0;
            String[] address = new String[10];
            Iterator ite = values.iterator();
            while (ite.hasNext()) {
                String record = ite.next().toString();
                int len = record.length();
                int i = 2;
                if (0 == len) {
                    continue;
                }
                // 取得左右表标识
                char relationtype = record.charAt(0);
                // 左表
                if ('1' == relationtype) {
                    factory[factorynum] = record.substring(i);
                    factorynum++;
                }
                // 右表
                if ('2' == relationtype) {
                    address[addressnum] = record.substring(i);
                    addressnum++;
                }
            }
            // 求笛卡尔积
            if (0 != factorynum && 0 != addressnum) {
                for (int m = 0; m  <pre class="brush:php;toolbar:false"> javac -classpath hadoop-core-1.1.2.jar:/opt/hadoop-1.1.2/lib/commons-cli-1.2.jar -d firstProject firstProject/MTJoin.java
Copy after login
jar -cvf MTJoin.jar -C firstProject/ .     
Copy after login

删除已经存在的output

hadoop fs -rmr output
Copy after login
hadoop fs -mkdir input
Copy after login
hadoop fs -put factory input
Copy after login
 hadoop fs -put address input
Copy after login

运行

hadoop jar  MTJoin.jar MTJoin input output
Copy after login


查看结果

 hadoop fs -cat output/part-r-00000
Copy after login










?

作者:a331251021 发表于2013-8-4 16:20:52 原文链接

阅读:72 评论:0 查看评论

hadoop实例---多表关联

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!