02Spark的左连接
两个文件,一个是用户的数据,一个是交易的数据。
用户:
交易:
流程如下:
分为以下几个步骤: (1)分别读取user文件和transform文件,并转为两个RDD.
* (2)对上面两个RDD执行maptopair操作。生成userpairRdd和transformpairRdd
* (3)对transformpairRdd和userpairRdd执行union操作,就是把上面的数据放在一起,生成allRdd
* (4)然后把allRdd用groupBykey分组,把同一个UserID的数据都放在一起。生成groupRdd。
* (5)对grouprdd处理,生成productLoctionRdd:(p1,UT),(p2,UT)这种productlistRdd。
* (6)productlistRdd这里面有数据重复,需要去重。
代码结构:
代码:
package com.test.book; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set; import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.PairFlatMapFunction;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2; public class LeftJoinCmain { /*
* 分为以下几个步骤: (1)分别读取user文件和transform文件,并转为RDD.
* (2)对上面两个RDD执行maptopair操作。生成userpairRdd和transformpairRdd
* (3)对transformpairRdd和userpairRdd执行union操作,就是把上面的数据放在一起,生成allRdd
* (4)然后把allRdd用groupBykey分组,把同一个UserID的数据都放在一起。生成groupRdd。
* (5)对grouprdd处理,生成productLoctionRdd:(p1,UT),(p2,UT)这种productlistRdd。
* (6)productlistRdd这里面有数据重复,需要去重。
*
*/ public static void main(String[] args) { SparkConf conf = new SparkConf().setAppName("LeftJoinCmain").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf);
// 导入user的数据
JavaRDD<String> user = sc.textFile("/Users/mac/Desktop/user.txt");
// 导入transform的数据
JavaRDD<String> transform = sc.textFile("/Users/mac/Desktop/transactions.txt"); // 生成一个JavaPairRDD,KEY是uerID,Value是Tuple的形式,("L",地址)
JavaPairRDD<String, Tuple2<String, String>> userpairRdd = user
.mapToPair(new PairFunction<String, String, Tuple2<String, String>>() { /**
*
*/
private static final long serialVersionUID = 1L; @Override
public Tuple2<String, Tuple2<String, String>> call(String line) throws Exception {
String[] args = line.split(" ");
return new Tuple2<String, Tuple2<String, String>>(args[0],
new Tuple2<String, String>("L", args[1]));
} }); // 生成一个transform,
JavaPairRDD<String, Tuple2<String, String>> transformpairRdd = transform
.mapToPair(new PairFunction<String, String, Tuple2<String, String>>() { /**
*
*/
private static final long serialVersionUID = 1L; @Override
public Tuple2<String, Tuple2<String, String>> call(String line) throws Exception {
String[] args = line.split(" "); return new Tuple2<String, Tuple2<String, String>>(args[2],
new Tuple2<String, String>("P", args[1]));
}
}); /**
* allRdd的格式是: { (userID,Tuple("L","UT")), (userID,Tuple("P","p3")) . . . }
*/
JavaPairRDD<String, Tuple2<String, String>> allRdd = userpairRdd.union(transformpairRdd); /**
* 这一步就是把同一个uerID的数据放在一起,结果是: (userID1,List[(Tuple2("L","UT"),//一个用户地址信息
* Tuple2("P","p1"),//其他的都是商品信息 Tuple2("P","p2") ] )
*/
JavaPairRDD<String, Iterable<Tuple2<String, String>>> groupRdd = allRdd.groupByKey(); /**
* 这一步就是从groupRdd中去掉userID,生成productLoctionRdd:(p1,UT),(p2,UT)这种。
*
*/ JavaPairRDD<String, String> productlistRdd = groupRdd.flatMapToPair(
new PairFlatMapFunction<Tuple2<String, Iterable<Tuple2<String, String>>>, String, String>() { @Override
public Iterable<Tuple2<String, String>> call(Tuple2<String, Iterable<Tuple2<String, String>>> t)
throws Exception { String location = "UNKNOWN";
Iterable<Tuple2<String, String>> pairs = t._2;
List<String> products = new ArrayList<String>();
for (Tuple2<String, String> pair : pairs) { if (pair._1.equals("L"))
location = pair._2;
if (pair._1.equals("P")) {
products.add(pair._2);
} } List<Tuple2<String, String>> kvList = new ArrayList<Tuple2<String, String>>(); for (String product : products) {
kvList.add(new Tuple2<String, String>(product, location)); }
return kvList;
}
}); // 把一个商品的所有地址都查出来 JavaPairRDD<String, Iterable<String>> productbylocation = productlistRdd.groupByKey();
List<Tuple2<String, Iterable<String>>> debug3 = productbylocation.collect(); for (Tuple2<String, Iterable<String>> value : debug3) { Iterator<String> iterator = value._2.iterator(); while (iterator.hasNext()) {
System.out.println(value._1 + ":" + iterator.next());
} } /**
* 上述代码经过调试, 结果如下: p2:GA p4:GA p4:UT p4:CA p1:UT p1:UT p1:GA p3:UT
*
*
* 发现有相同的商品和地址。我们需要把这个重复的结果去除。
*/
// 处理如下:我们用mapvalues()函数 JavaPairRDD<String, Tuple2<Set<String>, Integer>> productByuniqueLocation = productbylocation
.mapValues(new Function<Iterable<String>, Tuple2<Set<String>, Integer>>() { @Override
public Tuple2<Set<String>, Integer> call(Iterable<String> v1) throws Exception {
Set<String> uniquelocations = new HashSet<String>(); Iterator<String> iterator = v1.iterator(); while (iterator.hasNext()) { String value = iterator.next();
uniquelocations.add(value); } // 返回一个商品的所有地址,以及地址的个数。
return new Tuple2<Set<String>, Integer>(uniquelocations, uniquelocations.size());
}
}); List<Tuple2<String, Tuple2<Set<String>, Integer>>> finalresult = productByuniqueLocation.collect();
for (Tuple2<String, Tuple2<Set<String>, Integer>> vTuple2 : finalresult) { String aa=vTuple2._1;
Iterator<String> iterator=vTuple2._2._1.iterator();
while(iterator.hasNext())
{
System.out.println("商品的名字:"+aa+"所有的地址"+iterator.next()); } } } }
运行结果:
去重后的结果:
02Spark的左连接的更多相关文章
- mysql 内连接、左连接、右连接
记录备忘下,初始数据如下: DROP TABLE IF EXISTS t_demo_product; CREATE TABLE IF NOT EXISTS t_demo_product( proid ...
- 《Entity Framework 6 Recipes》中文翻译系列 (16) -----第三章 查询之左连接和在TPH中通过派生类排序
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-10应用左连接 问题 你想使用左外连接来合并两个实体的属性. 解决方案 假设你有 ...
- 数据库中的左连接(left join)和右连接(right join)区别
Left Join / Right Join /inner join相关 关于左连接和右连接总结性的一句话: 左连接where只影向右表,右连接where只影响左表. Left Join select ...
- MySQL的左连接、右连接和全连接的实现
表student:+----+-----------+------+| id | name | age |+----+-----------+------+| 1 | Jim | 18 || 2 | ...
- Oracle 左连接、右连接、全外连接、(+)号作用
分类: Oracle Oracle 外连接 (1)左外连接 (左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制) 外连接(Outer ...
- Linq连接查询之左连接、右连接、内连接、全连接、交叉连接、Union合并、Concat连接、Intersect相交、Except与非查询
内连接查询 内连接与SqL中inner join一样,即找出两个序列的交集 Model1Container model = new Model1Container(); //内连接 var query ...
- LINQ的左连接、右连接、内连接
.左连接: var LeftJoin = from emp in ListOfEmployees join dept in ListOfDepartment on emp.DeptID equals ...
- 数据库左连接left join、右连接right join、内连接inner join on 及 where条件查询的区别
join on 与 where 条件的执行先后顺序: join on 条件先执行,where条件后执行:join on的条件在连接表时过滤,而where则是在生成中间表后对临时表过滤 left joi ...
- SQL Server中的连接查询【内连接,左连接,右连接,。。。】
在查询多个表时,我们经常会用“连接查询”.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据 ...
随机推荐
- Android应用程序开发疑问
为什么android.util.log会提供五种不同级别的打印输出方式?(打印输出在Logcat窗口)比如:Log.v()用于打印比较琐碎的信息:Log.d()用于打印调试信息:Log.i()用于打印 ...
- 关于linux kernel slab内存管理的一点思考
linux kernel 内存管理是个很大的话题,这里记录一点个人关于slab模块的一点思考总结. 有些书把slab介绍成高速缓存,这会让人和cache,特别是cpu cache混淆,造成误解.sla ...
- ReactNative 常见红屏黄屏及终端报错
刚开始接触RN,总是会遇到各种红屏黄屏报错,红屏是fatal error(程序无法正常运行),黄屏是Warming(非致命错误,程序可以运行但是存在潜在问题可能在某些情况下将导致fatal error ...
- [CTSC2017]吉夫特
Description: 给定一个序列\(a_1,a_2,a_3...a_n\) 求有多少个不上升子序列: \(a_{b1},a_{b_2}...\) 满足 \(C_{a_{b1}}^{a_{b2}} ...
- 封装、property特性及绑定与非绑定方法
1.封装 (1)什么是封装? 封:属性对外是隐藏的,但对内是开放的: 装:申请一个名称空间,往里面装入一系列名字/属性 (2)为什么要封装? 封装数据属性的目的 首先定义属性的目的就是为了给类外部的使 ...
- BZOJ2268 : Wormly
考虑头部,一定是能向前就向前,因此是最左边的腿往右$b-1$个位置. 头部移动之后,腿部就要相应地移动到区间内最靠右的$l$个$1$之上. 若头部和腿部都不能移动,检查是否到达终点即可. 用前缀和以及 ...
- [NOIP2018]普及组游记
想不到自己还有机会写游记 ——sysky 考完一个月后 DAY -INF 报名 还为了拍照下载了一个PS 特地把自己P白了一点233 花里胡哨得提交了rg.noi.cn DAY -14~-2 停课集训 ...
- 微信小程序内联h5页面,实现分享
在小程序内直联h5的页面(pages/webview/webview.js),该页面为<web-view>的容器,使用<web-view>组件 <web-view wx: ...
- python基础-requests模块、异常处理、Django部署、内置函数、网络编程
网络编程 urllib的request模块可以非常方便地抓取URL内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应. 校验返回值,进行接口测试: 编码:把一个Python对象编码转 ...
- numpy中的广播机制
广播的引出 numpy两个数组的相加.相减以及相乘都是对应元素之间的操作. import numpy as np x = np.array([[2,2,3],[1,2,3]]) y = np.arra ...