【博学谷学习记录】超强总结,用心分享 | MapReduce实现reduce端join操作

#博学谷IT技术支持#

本篇文章描述了用MapReduce实现一个sql中的join操作过程,包含了Reduce端join和分组。

一、需求

有两张表,分别为订单表itheima_order_goods和商品表itheima_goods,要求实现将每个订单购买的商品信息放在订单后面作为一行输出。

订单表组成:订单id|商品id|商品价格

商品表组成:商品id|商品数量|商品名称

 二、思路

订单表

k1:行偏移量

v1:订单表一行

k2:商品id

v2:订单表一行

商品表

k1:行偏移量

v1:商品表一行

k2:商品id

v2:商品表一行

分组后相同k2合并,v2为购买了相同商品的订单信息及购买的商品信息,需要将不同的订单信息和商品信息提取作为k3,v3为NullWritable。

三、代码实现

map方法

获取读取的文件名称分别处理k2和v2,因为两张表的key均为商品id,为了区分在订单表的v2前面加上o_,在商品表的v2前面加上g_,方便后续处理。

public class ReduceJoinMapper extends Mapper<LongWritable, Text, Text, Text> {
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException {
        FileSplit fileSplit = (FileSplit) context.getInputSplit();
        String fileName = fileSplit.getPath().getName();
        String[] array = value.toString().split("\\|");

        if ("itheima_order_goods.txt".equals(fileName)) {
            String k2 = array[1];
            String v2 = "o_" + array[0] + "\t" + array[2];
            context.write(new Text(k2), new Text(v2));
        }
        if ("itheima_goods.txt".equals(fileName)) {
            String k2 = array[0];
            String v2 = "g_" + array[0] + "\t" + array[2];
            context.write(new Text(k2), new Text(v2));
        }
    }
}

reduce方法

将v2中订单信息提取放入集合中,分组后每一条中只有一个商品信息,因此将商品信息单独作为字符串保存,输出的k3为将集合中的信息与商品信息合并。

public class ReduceJoinReducer extends Reducer<Text, Text, Text, NullWritable>{
    @Override
    protected void reduce(Text key, Iterable<Text> values, Reducer<Text, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException {
        ArrayList<String> orderList = new ArrayList<>();
        String goods_value = "";
        for (Text value : values) {
            if (value.toString().startsWith("o_")) {
                orderList.add(value.toString().substring(2));
            }
            if (value.toString().startsWith("g_")) {
                goods_value = value.toString().substring(2);
            }
        }
        for (String order_value : orderList) {
            context.write(new Text(order_value + "\t" + goods_value), NullWritable.get());
        }
    }
}

排序

将相同的订单id放在一起输出

public static class ReduceJoinSortMapper extends Mapper<LongWritable, Text, Text, Text> {
        @Override
        protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException {
            context.write(new Text(value.toString().split("\t")[0]), value);
        }
    }

    public static class ReduceJoinSortReducer extends Reducer<Text, Text, Text, NullWritable> {
        @Override
        protected void reduce(Text key, Iterable<Text> values, Reducer<Text, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException {
            for (Text value : values) {
                context.write(value, NullWritable.get());
            }
        }
    }

 四、运行结果

每行结果为订单id,商品价格,商品id,商品名称,前两个为订单表中内容,后两个为商品表中内容。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值