自然链接

  例如,我们需要在属性ID上做关系R和关系S的自然连接。在Map阶段对于每一条R和S中的记录r,我们把它的ID的值作为键,其余属性的值以及R(S中的记录为S的名称)的名称作为值输出出去。在Reduce阶段我们则将统一键中所有的值,根据他们的来源(RR和S)分为两组做笛卡尔乘积然后将得到的结果输出出去。
         例如以上面的关系R和关系S为例。关系R中ID为1的记录会以键值对(1,(relation,张小雅,20,91))发射出去,而关系S中ID为1的记录会以键值对(1,(relationS,女,165))发射出去,这里在值前面添加来源关系的名称是为例Reduce端能够辨别键值对的来源。在Reduce端ID为1,的值有两个,按照它们的来源分组为两组(张小雅,20,91)和(女,165),然后将这两组进行笛卡尔乘积并添加上ID(也就是键)作为新的值发出去,这里新的值为:(1,张小雅,20,91,女,165)。
         自然连接操作Map端的实现代码如下:


    //自然连接操作Map端的实现代码    start
       public static class NaturalJoinMap extends  Mapper<Text, BytesWritable, Text,Text>{
          private int col;
          
          //获得用户设置的连接属性的列号
          protected void setup(Context context) throws IOException,InterruptedException {
              col =context.getConfiguration().getInt("col", 0);
          }
          
          protected void map(Text relationName,BytesWritable content, Context context) throws IOException ,InterruptedException {
              String[]records = newString(content.getBytes(),"UTF-8").split("\\n");
              for (int i = 0; i < records.length; i++) {
                 RelationArecord = newRelationA(records);
                 context.write(new Text(record.getCol(col)), newText(relationName.toString() + " " + record.getValueExcept(col)));
              }
          }
       }

 Map端首先从用户获得需要连接的属性的列号,谈后对于每一条记录,以相应属性上的值作为键,剩余的树形作为值发送键值对到Reduce端。

         Reduce端的实现代码如下:
      //Reduce端的实现代码如下
       public static class NaturalJoinRduce extends Reducer<Text, Text,Text, NullWritable>{
          //存储关系名称
          private String relationNameA;
          protected void setup(Context context) throws IOException,InterruptedException {
              relationNameA =context.getConfiguration().get("relationNameA");
          }
          protected void reduce(Text key,java.lang.Iterable<Text> values, Context context) throws IOException,InterruptedException {
              ArrayList<Text>setR = newArrayList<Text>();
              ArrayList<Text>setS = newArrayList<Text>();
              //按照来源分为两组,然后做笛卡尔乘积
              for (Text val : values) {
                 String[]recordInfo = val.toString().split(" ");
                 if(recordInfo[0].equalsIgnoreCase(relationNameA)){
                    setR.add(new Text(recordInfo[1]));
                 }else{
                    setS.add(new Text(recordInfo[1]));
                 }
              }
              for (int i = 0; i <setR.size(); i++) {
                 for (int j = 0; j <setS.size(); j++) {
                    Textt = newText(setR.get(i).toString() + "," + key.toString() + "," + setS.get(j).toString());
                    context.write(t,NullWritable.get());
                 }
              }
          }
       }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值