MapReduce表关联

今天重新学习了表关联,为了以后用到的时候能够快速想到。这里记录下来设计的思想:
由于多表关联跟单表关联一样,甚至如果是两个表,那么的结构更加清新,所以只记录单表关联
单表关联:
所谓单表关联,即使特殊的多表关联,表关联一个思想就是区分出左右表,最后求笛卡尔积即可!
实例:
child parent
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
要求:
grandchild grandparent
Tom alice
Tom jesse
… …
分析:
题目要求找到儿子辈和爷爷辈的关系,所以自然而然想到的是连接的桥梁是
父亲,但是源数据中每个人可能扮演不同的角色。怎么找到父亲的角色呢?
(这个“父亲”还有自己的父辈)
思路:
我们把源数据儿子的列和父亲的列切开,map阶段输出的时候分成两组输出:
第一组:
把源数据中的son列做kay,father做value输出,添加一个标记L作为左表
第二组:
把源数据中的father列做kay,son做value输出,添加一个标记R作为右表
为什么这么做呢?
因为我们不知道其中的人物扮演几个角色,所以我们索性把每个人的关系都输出
第一组:
我们输出了所有当过son的人
第二组:
我们输出了所有当过father的人
两组的输出的结果肯定有相同的key,也就是不但是儿子也是父亲的角色,这就是我们要
找的(还有父辈的父亲)角色。它里边的value是两种记录(含有L和R两种类型的记录)例如:
Key:jack=>iterator(L:tom jack; R: jack alice;…) // 当过儿子和父亲,左右表都有记录
那么其他的key的呢?
其他的key就是只当过儿子的或者只当过爷爷的角色例如:
Key:Lucy=>iterator(L:Lucy Mary;…) // 只当过儿子,只有左表中有记录
Key:Ben=>iterator(R:Ben Lucy;…) // 只当过爷爷,只有右表中有记录

这样,到了reduce端我们只需要处理每一个Key即可:
1.建立两个数组grandchild[]和grandparent[]
2.把L中的儿子取出放在grandchild[]
3.把R中的father取出放在grandparent[]
4.这个key可能有多个son和多个father,但是每个key的son和他的father都是存在爷孙关系的
所以用两个for()嵌套输出即可!(求笛卡尔积)

说明:
当对应的Key的Value中只有左表或者右表的记录,我们就把他过滤掉;
过滤的条件是:grandchild[] == 0 || grandparent[] == 0
只输出集合中含有L,R两个记录的key

关键代码:

map函数{
    string[] fields = value.toString().split("\t");
    String son = fields[0];
    String father = fields[1];
    String left = "L:";
    String right = "R:";
    context.write(new Text(son), new Text(left+son+","+father));    // 第一组
    context.write(new Text(father), new Text(right+son+","+father));    // 第二组

}
reduce函数{
    String[] grandchild = new String[10];
    int i = 0;
    String[] grandparent = new String[10];
    int j = 0;
    for(Text text:Iterator){
        String line = text.toString();
        if(line.contains("L"){
            grandchild[i++] = line.subString("取出son");
        }else{
            grandparent[j++] = line.subString("取出father");
        }
    }

    if(i != 0 && j != 0){       // 输出笛卡尔积
        for(int m = 0; m < grandchild.length; m++){
            for(int n = 0; n < grandparent.length; n++){
                context.write(new Text(grandchild[m], new Text(grandparent[n])))
            }
        }
    }

}

图示说明:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值