MapReduce清洗json数据——去空去重并使用指定符号分隔数据

咳咳,终于要写mapreduce了,算是填上了以前挖的坑,虽然时间有点晚。。。。。。

mapreduce去空去重并格式化输出数据

前提:解析json的库:我使用的是阿里的fastjson

思路:

数据去重:map的输出<key,value>经过shuffle过程聚集成<key,value-list>后交给reduce,无论这个数据出现多少次,只要在最终结果中输出一次就可以了。具体就是reduce的输入应该以数据作为key,而对value-list则没有要求(可以设置为空)。当reduce接收到一个<key,value-list>时就直接将输入的key复制到输出的key中,并将value设置成空值,然后输出<key,value>。

数据去空:map阶段在读取一行数据时我们将这一行数据分割放到一个数组中遍历这个数组并判断它是不是空如果是空我们可以删除这条数据也可以使用指定值填充。

分隔数据:在map阶段我们将分割好的数据放在一个数组中,遍历这个数组时使用字符串拼接的方式拼接上指定符号并将它作为key输出

分析:

先来看一下数据的格式:
在这里插入图片描述
数据的第一行和最后一行是 ‘[’ 和 ‘]’ 如果我们读取到的行包含这两个符号或读取的行为空则不做任何处理。
然后我们发现每条数据的最后都有一个逗号,我们需要删除每行最后的逗号,然后就是解析json数据然后提取相应字段。
map代码:

import com.alibaba.fastjson.JSONObject;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class CleanMap extends Mapper<LongWritable,Text,Text,NullWritable> {
    private static Text text = new Text();
    public void map(LongWritable key,Text value,Context context) throws IOException, InterruptedException {
        String line = value.toString();
        //判断读取的行是否包含“[” 和 “]” 或读取的行为空
        if (line.indexOf("[")==0 || line.indexOf("]")==0 || line.trim().isEmpty()){
            return;
        }
        //删除逗号
        line = line.substring(0, line.length()-1);
        //删除逗号时可能会删掉每行最后的"}"就是判断数据是否符合json格式这里我们要加一层判断否则解析json数据会出错
        if (!line.endsWith("}")){
            line = line.concat("}");
        }
        //解析json数据
        JSONObject jsonObject = JSONObject.parseObject(line);
        String[] data = new String[5];
        String name = jsonObject.getString("name");
        判断name字段是否为空
        if (name==null || name.trim().isEmpty()) {
            return;
        }
        data[0] = jsonObject.getString("rank");
        data[1] = name.trim();
        data[2] = jsonObject.getString("actors");
        data[3] = jsonObject.getString("time");
        data[4] = jsonObject.getString("score");
        //循环判空
        for(String i : data) {
            if(i==null||i.equals("")) {
                return;
            }
        }
        //分隔数据
        String end = "";
        for (String item: data){
            end = end + item + "|";
        }
        end = end.substring(0, end.length()-1);
        //将数据转为text类型并作为key输出
        text.set(end);
        context.write(text, NullWritable.get());
    }
}
reduce不需要做任何处理直接输出即可

reduce代码:

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

public class CleanReduce extends Reducer<Text, NullWritable, Text, NullWritable> {
    public void reduce(Text key, Iterable<NullWritable> value, Context context) throws IOException, InterruptedException {
        context.write(key, NullWritable.get());
    }
}

main:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;

public class CleanJob {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);
        job.setJarByClass(CleanJob.class);
        job.setMapperClass(CleanMap.class);
        job.setReducerClass(CleanReduce.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(NullWritable.class);
        Path in = new Path("hdfs://localhost:9000/maoyan/in/");
        Path out = new Path("hdfs://localhost:9000/maoyan/out");
        FileInputFormat.addInputPath(job, in);
        FileOutputFormat.setOutputPath(job, out);
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }

}

以上就是去空去重以及分割数据的全部代码!希望对大家有所帮助!
看一下运行效果:
在这里插入图片描述
在这里插入图片描述

  • 11
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值