Hadoop基础--统计商家id的标签数案例分析

                               作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.项目需求

  将“temptags.txt”中的数据进行分析,统计出商家id的评论标签数量,由于博客园无法上传大文件的文本,因此我把该文本的内容放在博客园的另一个链接了(需要的戳我),如果网页打不开的话也就可以去百度云盘里下载副本,链接:https://pan.baidu.com/s/1daRiwOVe6ohn42fTv6ysJg 密码:h6er。

  实现效果如下:

二.代码实现

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.taggen; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import java.util.ArrayList;
import java.util.List; public class Util {
public static List<String> taggen(String comment){
//解析传进来的字符串
JSONObject jo = JSON.parseObject(comment);
//拿到包含商家评论的相关的标签
JSONArray jArray = jo.getJSONArray("extInfoList");
//过滤掉不含商家评论的标签
if(jArray != null && jArray.size() != 0){
//定义一个空的有序集合
List<String> list = new ArrayList<String>();
//通过jArray得到第一个json串,作为json对象
JSONObject jo2 = jArray.getJSONObject(0);
//进一步拿到商家评论的相关的标签
JSONArray jArray2 = jo2.getJSONArray("values");
//进一步过滤掉不含商家评论的标签
if(jArray2 != null && jArray2.size() != 0){
for (Object obj : jArray2) {
//将商检评论的标签添加到我们定义的集合中
list.add(obj.toString());
}
return list;
}
}
return null;
}
}

Util.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.taggen; import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; public class TagBean implements WritableComparable<TagBean> {
private String tag;
private int count; /**
* compareTo() 方法用于将 Number 对象与方法的参数进行比较。可用于比较 Byte, Long, Integer等。
* 该方法用于两个相同数据类型的比较,两个不同类型的数据不能用此方法来比较。
*/
public int compareTo(TagBean o) {
if(o.count == this.count){
return this.getTag().compareTo(o.getTag());
}
return o.count - this.count;
} public void write(DataOutput out) throws IOException {
out.writeUTF(tag);
out.writeInt(count);
}
public void readFields(DataInput in) throws IOException {
tag = in.readUTF();
count = in.readInt();
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}

TagBean.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.taggen; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException;
import java.util.List; public class TaggenMapper extends Mapper<LongWritable,Text,Text,IntWritable> { /**
*
* @param key //这是读取行的偏移量
* @param value //这是这是的数据,每条数据格式都类似,比如:70611801 {"reviewPics":null,"extInfoList":null,"expenseList":null,"reviewIndexes":[1,2],"scoreList":[{"score":4,"title":"环境","desc":""},{"score":5,"title":"服务","desc":""},{"score":4,"title":"口味","desc":""}]}
* @param context
*/
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] arr = line.split("\t");
String id = arr[0];
String json = arr[1];
//我们对数据进行解析,把用户评论的标签数都整合起来,用tags变量来接受数据
List<String> tags = Util.taggen(json);
//如果tags没数据,则不写入
if(tags != null && tags.size() != 0){
for(String tag : tags){
//给数据打标签,最终结果类似于 : 70611801_价格实惠
String compKey = id+ "_"+ tag;
context.write(new Text(compKey), new IntWritable(1));
}
}
}
}

TaggenMapper.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.taggen; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; public class TaggenReducer extends Reducer<Text, IntWritable , Text, IntWritable> {
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
Integer sum = 0;
for(IntWritable value : values){
sum += value.get();
}
context.write(key, new IntWritable(sum));
}
}

TaggenReducer.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.taggen; import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; public class TaggenMapper2 extends Mapper<Text,Text, Text,Text> { //89223651_价格实惠 8
@Override
protected void map(Text key, Text value, Context context) throws IOException, InterruptedException { //此时的key其实就是上一个MapReduce的结果,比如:70611801_价格实惠
String compkey = key.toString();
//我们将结果进行拆分,取出来id,比如 : 70611801
String id = compkey.split("_")[0];
//我们将结果进行拆分,取出来tag,比如 : 价格实惠
String tag = compkey.split("_")[1];
//此时的value的值其实就是对key的一个计数 : 比如key出现的次数为8
String sum = value.toString();
//这个时候我们就是将tag和之前的value进行拼接,得出结果如下 : 价格实惠_8
String newVal = tag + "_" + sum;
//最后将我们重写组合的key和value重新分发给reduce
context.write(new Text(id), new Text(newVal));
}
}

TaggenMapper2.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.taggen; import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException;
import java.util.TreeSet; public class TaggenReducer2 extends Reducer<Text,Text,Text,Text> { protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
//使用TreeSet的目的是实现去重并排序
TreeSet<TagBean> ts = new TreeSet<TagBean>();
//迭代value,并将其放入treeSet,而TreeSet使用的排序是自定义(TagBean)的。
for(Text value:values){
String[] arr = value.toString().split("_");
String tag = arr[0];
int count = Integer.parseInt(arr[1]);
TagBean tagBean = new TagBean();
tagBean.setTag(tag);
tagBean.setCount(count);
ts.add(tagBean);
}
//迭代TreeSet中的TagBean,并得到tag和count,放进StringBuffer
StringBuffer sb = new StringBuffer();
for (TagBean tb : ts) {
String tag = tb.getTag();
int count = tb.getCount();
String val = tag+"_"+count;
sb.append(val+ ",");
}
String newVal = sb.toString().substring(0, sb.length() -1);
//经过上面的整理,可以把同一个商家id的所有标签整个到一起,最终发送出去FileOutputFormat,最终格式为类型如 : 83084036 价格实惠_1,干净卫生_1
context.write(key,new Text(newVal));
//TreeSet置空
ts.clear();
//StringBuffer置空
sb.setLength(0);
}
}

TaggenReducer2.java 文件内容

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.taggen; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class TaggenApp { public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
conf.set("fs.defaultFS","file:///");
FileSystem fs = FileSystem.get(conf);
Job job = Job.getInstance(conf);
job.setJobName("taggen");
job.setJarByClass(TaggenApp.class);
job.setMapperClass(TaggenMapper.class);
job.setReducerClass(TaggenReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
Path outPath = new Path("D:\\10.Java\\IDE\\yhinzhengjieData\\MyHadoop\\out");
if(fs.exists(outPath)){
fs.delete(outPath,true);
}
FileInputFormat.addInputPath(job,new Path("D:\\10.Java\\IDE\\yhinzhengjieData\\MyHadoop\\temptags.txt"));
FileOutputFormat.setOutputPath(job,outPath);
if(job.waitForCompletion(true)){
Job job2 = Job.getInstance(conf);
job2.setJobName("taggen2");
job2.setJarByClass(TaggenApp.class);
job2.setMapperClass(TaggenMapper2.class);
job2.setReducerClass(TaggenReducer2.class);
job2.setOutputKeyClass(Text.class);
job2.setOutputValueClass(Text.class);
job2.setInputFormatClass(KeyValueTextInputFormat.class);
Path outPath2 = new Path("D:\\10.Java\\IDE\\yhinzhengjieData\\MyHadoop\\out2");
if(fs.exists(outPath2)){
fs.delete(outPath2,true);
}
FileInputFormat.addInputPath(job2,outPath);
FileOutputFormat.setOutputPath(job2,outPath2);
job2.waitForCompletion(true);
}
}
}

Hadoop基础--统计商家id的标签数案例分析的更多相关文章

  1. Scala进阶之路-统计商家id的标签数以及TopN示例案例分析

    Scala进阶之路-统计商家id的标签数以及TopN示例案例分析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.项目需求 将“temptags.txt”中的数据进行分析,统计出 ...

  2. Hadoop基础-Map端链式编程之MapReduce统计TopN示例

    Hadoop基础-Map端链式编程之MapReduce统计TopN示例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.项目需求 对“temp.txt”中的数据进行分析,统计出各 ...

  3. Hadoop基础-MapReduce的工作原理第一弹

    Hadoop基础-MapReduce的工作原理第一弹 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在本篇博客中,我们将深入学习Hadoop中的MapReduce工作机制,这些知识 ...

  4. hadoop基础----hadoop理论(四)-----hadoop分布式并行计算模型MapReduce具体解释

    我们在前一章已经学习了HDFS: hadoop基础----hadoop理论(三)-----hadoop分布式文件系统HDFS详细解释 我们已经知道Hadoop=HDFS(文件系统,数据存储技术相关)+ ...

  5. Hadoop基础-MapReduce的常用文件格式介绍

    Hadoop基础-MapReduce的常用文件格式介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MR文件格式-SequenceFile 1>.生成SequenceF ...

  6. Hadoop基础-MapReduce的Combiner用法案例

    Hadoop基础-MapReduce的Combiner用法案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编写年度最高气温统计 如上图说所示:有一个temp的文件,里面存放 ...

  7. Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例)

    Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑配置文件(pml.xml)(我 ...

  8. Hadoop基础原理

    Hadoop基础原理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 业内有这么一句话说:云计算可能改变了整个传统IT产业的基础架构,而大数据处理,尤其像Hadoop组件这样的技术出 ...

  9. hadoop基础----hadoop实战(七)-----hadoop管理工具---使用Cloudera Manager安装Hadoop---Cloudera Manager和CDH5.8离线安装

    hadoop基础----hadoop实战(六)-----hadoop管理工具---Cloudera Manager---CDH介绍 简介 我们在上篇文章中已经了解了CDH,为了后续的学习,我们本章就来 ...

随机推荐

  1. grunt源码解析:整体运行机制&grunt-cli源码解析

    前端的童鞋对grunt应该不陌生,前面也陆陆续续的写了几篇grunt入门的文章.本篇文章会更进一步,对grunt的源码进行分析.文章大体内容内容如下: grunt整体设计概览 grunt-cli源码分 ...

  2. Tkernel Package NCollection哈希基础的类

    OpenCASCADE内用到了很多由诸如NCollection_Map, NCollection_DataMap, NCollection_DoubleMap, NCollection_Indexed ...

  3. From today 2019.02.27

    HIT开设软件构造课程,需要在博客上分享记录学习体验,感觉还是挺好的. 以后会不定期更新一些关于学下java的笔记和实验相关的内容.

  4. UI Recorder 功能详解

    前言: UI Recorder安装教程见:UI Recorder 安装教程(一).UI Recorder 安装教程(二) 本次着重介绍UI Recorder录制过程中的功能按钮:添加悬停,添加断言,使 ...

  5. mysql新监语句需要前面加SET FOREIGN_KEY_CHECKS=0;

    SET FOREIGN_KEY_CHECKS=0; -- ------------------------------ Table structure for guestbook-- -------- ...

  6. linux gcc编译多个源文件的方法

    http://blog.csdn.net/yinjiabin/article/details/7731817

  7. linux第四章笔记

    第四章 进程调度 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间.进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统. 最大限度利用处理器时间的原则:只要有可以执行 ...

  8. Linux内核分析作业第二周

    操作系统是如何工作的 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 1.计算机工作三 ...

  9. Linux内核分析 笔记四 系统调用的三个层次 ——by王玥

    一.知识点总结 (一)用户态.内核态和中断 1.内核态:在高的执行级别下,代码可以执行特权指令,访问任意的物理地址,这时的CPU就对应内核态 2.用户态:在低级别的指令状态下,代码 只能在级别允许的特 ...

  10. 20135323符运锦----第三周:构建一个简单的Linux系统MenuOS

    相关知识点 1.arch目录 占据相当庞大的空间,X86目录下代码需要重点关注. 2.init目录 内核启动的相关代码基本都在此目录下,内含MAIN.C,文件中START_KERNEL是整个LINUX ...