IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【大数据离线开发】6.3 MapReduce案例锦集 -> 正文阅读

[大数据]【大数据离线开发】6.3 MapReduce案例锦集

6.3 MapReduce案例集锦

6.3.1 数据去重

复习SQL:distinct去掉重复的数据,作用于后面所有的列,只要组合起来的数据不一样就可以

一个列:
	select job from emp;
	select distinct job from emp;
多个列:
	select distinct deptno, job from emp;

案例:使用 MapReduce 实现 distinct 对一个列的去重

DistinctMapper.java

public class DistinctMapper extends Mapper<LongWritable, Text, Text, NullWritable> {
    @Override
    protected void map(LongWritable key1, Text value1, Context context) throws IOException, InterruptedException {
        String data = value1.toString();

        String[] words = data.split(",");

        context.write(new Text(words[2]),NullWritable.get());
    }
}

DistinctReducer.java

public class DistinctReducer extends Reducer<Text, NullWritable, Text, NullWritable> {
    @Override
    protected void reduce(Text key3, Iterable<NullWritable> values3, Context context) throws IOException, InterruptedException {
        context.write(key3, NullWritable.get());
    }
}

DistinctMain.java

public class DistinctMain {
    public static void main(String[] args) throws Exception {
        //1、创建一个任务,指定任务的入口
        Job job = Job.getInstance(new Configuration());
        job.setJarByClass(DistinctMain.class);

        //2、指定任务的map和map输出的数据类型
        job.setMapperClass(DistinctMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(NullWritable.class);

        //3、指定任务的Reduce
        job.setReducerClass(DistinctReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(NullWritable.class);

        //4、指定任务的输入路径、任务的输出路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        //5、执行任务
        job.waitForCompletion(true);
    }
}

在这里插入图片描述

在这里插入图片描述

6.3.2 多表查询:等值连接

复习多表查询:关系型数据库中的多表查询(子查询:在 Oracle 中,绝大多部分的组查询都是转换成多表查询来执行)

  1. 笛卡尔积:列数相加,行数相乘,如果不设置条件,查询出来的结果是笛卡尔积全集(列数相乘)
  2. 根据连接条件的不同
    • 等值连接
    • 不等值连接
    • 外连接
    • 自连接

在这里插入图片描述

案例:等值连接实现下面的SQL语句

select ename, dname from emp, dept where emp.deptno = dept.deptno;

在这里插入图片描述

EqualJoinMapper.java

public class EqualJoinMapper extends Mapper<LongWritable, Text, IntWritable, Text> {
    @Override
    protected void map(LongWritable key1, Text value1, Context context) throws IOException, InterruptedException {
        String data = value1.toString();

        String[] words = data.split(",");

        //判断数组的长度
        if (words.length == 3){
            //得到的是部门数据:部门号 部门名称
            context.write(new IntWritable(Integer.parseInt(words[0])), new Text("*"+words[1]));
        }else {
            //得到的是员工数据:员工的部门号 员工姓名
            context.write(new IntWritable(Integer.parseInt(words[7])), new Text(words[1]));
        }
    }
}

EqualReducer.java

public class EqualReducer extends Reducer<IntWritable, Text ,Text, Text> {
    @Override
    protected void reduce(IntWritable key3, Iterable<Text> values3, Context context) throws IOException, InterruptedException {
        //处理v3:可能是部门名称,也可能是员工的姓名
        String dname = "";
        String empNameList = "";

        for (Text value:values3) {
            String str = value.toString();

            int index = str.indexOf("*");
            if (index >= 0){
                //代表是部门的名称
                dname = str.substring(1);
            }else {
                //代表的是员工的名称
                empNameList = str + ";" + empNameList;
            }
        }

        context.write(new Text(dname), new Text(empNameList));
    }
}

EqualJoinMain.java

public class EqualJoinMain {
    public static void main(String[] args) throws Exception {
        //1、创建一个任务,指定任务的入口
        Job job = Job.getInstance(new Configuration());
        job.setJarByClass(EqualJoinMain.class);

        //2、指定任务的map和map输出的数据类型
        job.setMapperClass(EqualJoinMapper.class);
        job.setMapOutputKeyClass(IntWritable.class);
        job.setMapOutputValueClass(Text.class);

        //3、指定任务的Reduce
        job.setReducerClass(EqualReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        //4、指定任务的输入路径、任务的输出路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        //5、执行任务
        job.waitForCompletion(true);
    }
}

在这里插入图片描述

在这里插入图片描述

6.3.3 多表查询:自连接

自连接就是一张表的连接操作

举例:查询员工信息,要求显示:员工老版的名字 员工的名字

select b.ename, e.ename
from emp b, emp e
where b.empno = e.mgr;

在Oracle中,当查询的数据满足是一棵树的时候,可以使用层次查询来取代自连接

在这里插入图片描述

SelfJoinMapper.java

public class SelfJoinMapper extends Mapper<LongWritable, Text, IntWritable,Text> {
    @Override
    protected void map(LongWritable key1, Text value1, Context context) throws IOException, InterruptedException {
        /**
         *注意一个问题:如果数据存在非法数据,一定要处理一下(数据清洗)
         * 如果产生意外,一定要捕获
         */
        //数据:7654,MARTIN,SALESMAN,7698,1998/9/29,1250,1400,30
        String data = value1.toString();
        String[] words = data.split(",");

        // 作为老板表,输出员工号
        context.write(new IntWritable(Integer.parseInt(words[0])), new Text("*" + words[1]));

        // 作为员工表,输出老板号
        context.write(new IntWritable(Integer.parseInt(words[3])), new Text(words[1]));
    }
}

SelfJoinReduce.java

public class SelfJoinReduce extends Reducer<IntWritable, Text, Text, Text> {
    @Override
    protected void reduce(IntWritable key3, Iterable<Text> values3, Context context) throws IOException, InterruptedException {
        String bossName = "";
        String empNameList = "";

        for (Text t : values3){
            String str = t.toString();
            //判断是否存在*号
            int index = str.indexOf("*");
            if (index >= 0){
                //老板的姓名
                bossName = str.substring(1);
            }else {
                //员工的姓名
                empNameList = str + ";" + empNameList;
            }
        }

        //输出:如果存在老师,也存在员工,才进行输出
        if (bossName.length() > 0 && empNameList.length() > 0) {
            context.write(new Text(bossName), new Text(empNameList));
        }
    }
}

SelfJoinMain.java

public class SelfJoinMain {
    public static void main(String[] args) throws Exception {
        //1、创建一个任务,指定任务的入口
        Job job = Job.getInstance(new Configuration());
        job.setJarByClass(SelfJoinMain.class);

        //2、指定任务的map和map输出的数据类型
        job.setMapperClass(SelfJoinMapper.class);
        job.setMapOutputKeyClass(IntWritable.class);
        job.setMapOutputValueClass(Text.class);

        //3、指定任务的Reduce
        job.setReducerClass(SelfJoinReduce.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        //4、指定任务的输入路径、任务的输出路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        //5、执行任务
        job.waitForCompletion(true);
    }
}

在这里插入图片描述

在这里插入图片描述

6.3.4 倒排索引

6.3.5使用单元测试

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:37:17  更:2022-07-21 21:38:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:18:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码