用概要模式和过滤模式解决问题
前言
T1已经提到概要模式,T2介绍一下过滤模式:
过滤模式:查看数据的子集,比如某一用户产生的记录。
过滤模式的共同点在于不会去改变原有的记录,这些模式都是寻找数据子集的,不管结果集的规模是大还是小。过滤模式和前面提到的概要模式的差异是,它们是通过对数据的相似字段做概要与分组来得到数据的高层次视图。过滤更关注细小的数据,例如特殊用户生成的所有记录,或文本中用得最多的前10个动词。简单来说,过滤模式让数据被看得更清。过滤模式也可被认为是一种搜索形式,比如需要找出所有具备特定信息的记录,那么就过滤掉不匹配搜索条件的其他记录。
抽取数据集中的样本是过滤模式的一个常见应用,比如,抽取某字段值的最高记录。抽样可以被用来得到更小的、更具代表性的数据子集,这样将范围缩小后再来分析可以让某些运行更高效。
找出小部分数据的方法有多种,每种过滤模式与其他模式都有细微的差别,即便这些模式基本上做的事情相同。这些模式只需进行Map操作就行,不需要使用Reducer。
以下是本次任务的内容
一、任务目标
源数据是机场免税店销售数据
1.统计每天的销售金额;
2.统计不同航站楼每天的销售金额;
3.过滤出购买了两次的记录。
二、处理代码
1.Q1
定义Mapper,在Mapper里计算两次花费的总和,并输出键值对,以日期为键,两次花费总和为值
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String s = value.toString();
if (s.trim().length() > 0 && !s.contains("city_of_airport")) {
String[] strings = s.split(",");
String dt = strings[29];
Double cost = Double.parseDouble(strings[16]) + Double.parseDouble(strings[17]);
k.set(dt);
v.set(cost+"");
context.write(k, v);
}
}
定义Reducer,在Reduce里汇总每天的花费总和
protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
double costSum = 0;
for (Text value : values) {
costSum += Double.parseDouble(value.toString());
}
v.set(costSum+"");
context.write(key,v);
}
输出结果:
2.Q2
航站楼和日期作为键
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String s = value.toString();
if (s.trim().length() > 0 && !s.contains("city_of_airport")) {
String[] strings = s.split(",");
String dt = strings[29];
Double cost = Double.parseDouble(strings[16]) + Double.parseDouble(strings[17]);
String concourse = strings[20];
k.set(concourse + "\t" + dt);
v.set(cost+"");
context.write(k, v);
}
}
Reduce部分和Q1一样,做累加求和输出
输出结果:
3.Q3
用过滤模式进行过滤输出,输出结果在后面
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String s = value.toString();
if (s.trim().length() > 0 && !s.contains("city_of_airport")) {
String[] strings = s.split(",");
String hasC2 = strings[15];
if ("TRUE".equals(hasC2)){
v.set(s);
context.write(k, v);
}
}
}
for (Text value : values) {
v.set(value.toString());
context.write(null,v);
}
总结
Q1与Q2是用概要模式处理,定义相应的Mapper和Reducer进行具体操作,Q3则用到了过滤模式,而过滤模式的操作关键就在于Mapper的具体分析,Reduce部分也就是做输出。