hadoop学习--多表关联

来源:互联网 发布:软土路基沉降观测数据 编辑:程序博客网 时间:2024/06/05 09:09

本例从多个表中提取出所需要的信息。

输入是2个文件,一个表示工厂表,包含工厂名和地址编号;另一个表示地址表,包含地址名和地址编号。根据2个表的信息输出工厂名-地址名表。

factory.txt:

factorynameaddressedBeijing Red Star1Shenzhan Thunder3Guangzhou Honda2Beijing Rising1Guangzhou Development Bank2Tencent3Bank of Beijing1

address.txt:

addressIDaddressname1Beijing2Guangzhou3Shenzhen5Hangzhou

输出:

factorynameaddressnameBeijing Red StarBeijingBeijing RisingBeijingBank of BeijingBeijingGuangzhou HondaGuangzhouGuangzhou Development BankGuangzhouShenzhan ThunderShenzhenTencentShenzhen1、设计思路

在map阶段,对于每个输入以adressID为key进行保存;

来自factory.txt则存为:

<1,2:Beijing Red Star>

<3,2:Shenzhan Thunder>

...

来自address.txt则存为

<1,1:Beijing>

<2,1:Guangzhou>

...

这里的value开头的1: 2: 用来区分来自不同的表,将在reduce中用到。


在reduce阶段

对于相同的key,保存相应的factoryname和addressname。具体细节可参考上一篇单表关联部分。

2、程序代码

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import java.io.IOException;  
  2. import java.util.StringTokenizer;  
  3. import java.util.*;  
  4.   
  5. import org.apache.hadoop.conf.Configuration;  
  6. import org.apache.hadoop.fs.Path;  
  7. import org.apache.hadoop.io.IntWritable;  
  8. import org.apache.hadoop.io.Text;  
  9. import org.apache.hadoop.mapreduce.Job;  
  10. import org.apache.hadoop.mapreduce.Mapper;  
  11. import org.apache.hadoop.mapreduce.Reducer;  
  12. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  13. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  14. import org.apache.hadoop.util.GenericOptionsParser;  
  15.   
  16. public class MTjoin {  
  17.   
  18.   public static class TokenizerMapper   
  19.        extends Mapper<Object, Text, Text, Text>{  
  20.         
  21.     String tabletype = new String();  
  22.     String childname = new String();  
  23.     String parentname = new String();  
  24.     public void map(Object key, Text value, Context context  
  25.                     ) throws IOException, InterruptedException {  
  26.       String line = value.toString();  
  27.       int i = 0;  
  28.       if(line.contains("factoryname") == true || line.contains("addressID") == true)  
  29.       {  
  30.         return;  
  31.       }  
  32.       while(line.charAt(i) > '9' || line.charAt(i) < '0')  
  33.       {  
  34.         i++;  
  35.       }  
  36.       if(i == 0)        //address  
  37.       {  
  38.         int j = i + 1;  
  39.         while(line.charAt(j) != ' ')j++;  
  40.         String[] values = {line.substring(0,j),line.substring(j+1)};  
  41.         context.write(new Text(values[0]),new Text("1:" + values[1]));  
  42.       }  
  43.       else              //name  
  44.       {  
  45.         int j = i - 1;  
  46.         while(line.charAt(j) != ' ')j--;  
  47.         String[] values = {line.substring(0,j),line.substring(i)};  
  48.         context.write(new Text(values[1]),new Text("2:" + values[0]));  
  49.       }  
  50.     }  
  51.   }  
  52.     
  53.   public static class IntSumReducer   
  54.        extends Reducer<Text,Text,Text,Text> {  
  55.     private IntWritable result = new IntWritable();  
  56.     int count = 0;  
  57.   
  58.     public void reduce(Text key, Iterable<Text> values,   
  59.                        Context context  
  60.                        ) throws IOException, InterruptedException {  
  61.       if(count == 0)  
  62.       {  
  63.         context.write(new Text("factoryname"),new Text("addressname"));  
  64.         count++;  
  65.       }  
  66.       int factorynum = 0;  
  67.       int addressnum = 0;  
  68.       String[] factoryname = new String[10];  
  69.       String[] addressname = new String[10];  
  70.       String strrecord = new String();  
  71.       String[] strArr = new String[3];  
  72.       Iterator ite = values.iterator();  
  73.       while(ite.hasNext())  
  74.       {  
  75.         strrecord = ite.next().toString();  
  76.         if(strrecord.length()<=0)  
  77.         {  
  78.             continue;  
  79.         }  
  80.         char type = strrecord.charAt(0);  
  81.         if(type == '1')  
  82.         {  
  83.             addressname[addressnum++] = strrecord.substring(2);  
  84.         }  
  85.         else if(type == '2')  
  86.         {  
  87.             factoryname[factorynum++] = strrecord.substring(2);  
  88.         }  
  89.       }  
  90.       if(factorynum != 0 && addressnum != 0)  
  91.       {  
  92.         for(int i = 0;i < factorynum;i++)  
  93.         {  
  94.             for(int j = 0; j < addressnum;j++)  
  95.             {  
  96.                 context.write(new Text(factoryname[i]),new Text(addressname[j]));  
  97.             }  
  98.         }  
  99.       }  
  100.         
  101.     }  
  102.   }  
  103.   
  104.   public static void main(String[] args) throws Exception {  
  105.     Configuration conf = new Configuration();  
  106.     String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();  
  107.     if (otherArgs.length != 3) {  
  108.       System.err.println("Usage: MTjoin <in> <out>");  
  109.       System.exit(2);  
  110.     }  
  111.     Job job = new Job(conf, "MTjoin");  
  112.     job.setJarByClass(MTjoin.class);  
  113.     job.setMapperClass(TokenizerMapper.class);  
  114.     //job.setCombinerClass(IntSumReducer.class);  
  115.     job.setReducerClass(IntSumReducer.class);  
  116.     job.setOutputKeyClass(Text.class);  
  117.     job.setOutputValueClass(Text.class);  
  118.     FileInputFormat.addInputPath(job, new Path(otherArgs[0]));  
  119.     FileInputFormat.addInputPath(job, new Path(otherArgs[1]));  
  120.     FileOutputFormat.setOutputPath(job, new Path(otherArgs[2]));  
  121.     System.exit(job.waitForCompletion(true) ? 0 : 1);  
  122.   }  

0 0
原创粉丝点击