楔子
Spark 分析电影
使用广播机制查找18岁喜爱的电影Top10。主要是广播机制的使用
思路
分为2部分:1 是广播 符合年龄的userid ,2是 求Top10
第一部分
- 过滤年龄 选取其中符合年龄的userid
- 上述userid 抽取到list中,广播出去
第二部分
3. 电影转为key-value (电影id,电影名) 转为map
4. 评分 转为 key-value (用户id,电影id),期间使用 第一部分的广播变量过滤符合年龄的userid
5. 上述结果 变为 key-value (电影ID,1),然后在进行聚合操作 变为(电影id,观看总次数),然后交换 key-value
6. 取Top10 查找电影名打印
demo
/**
* 年龄18岁最喜爱的电影
*
* @param sparkSession
* @param userRdd
* @param ratRdd
* @param moviesRdd
*/
public static void age18PopularByRDD(SparkSession sparkSession, JavaRDD<String> userRdd, JavaRDD<String> ratRdd, JavaRDD<String> moviesRdd) {
// 用户中挑选年龄18 岁的 key-value :(userid:age)
JavaPairRDD<String, String> userfilter = userRdd.mapToPair(t -> new Tuple2<String, String>(t.split("::")[0], t.split("::")[2])).filter(t -> t._2.equals("18"));
List<String> userList = userfilter.map(t -> t._1).collect();// 这个集合不能add
// Java创建ClassTag的方法https://blog.csdn.net/hhtop112408/article/details/78338716
JavaSparkContext javaSparkContext = new JavaSparkContext(sparkSession.sparkContext());
final Broadcast<List<String>> broadcast = javaSparkContext.broadcast(userList);
// step 1 电影 (电影id,电影名字)
JavaPairRDD<String, String> movie_id_name = moviesRdd.mapToPair(t -> new Tuple2<String, String>(t.split("::")[0], t.split("::")[1]));
movie_id_name.cache();
Map<String, String> movie_map = movie_id_name.collectAsMap();
// step 2 评分(用户id,电影id)
JavaPairRDD<String, String> movieFilter = ratRdd.mapToPair(t -> new Tuple2<String, String>(t.split("::")[0], t.split("::")[0])).filter(new Function<Tuple2<String, String>, Boolean>() {
@Override
public Boolean call(Tuple2<String, String> v1) throws Exception {
return broadcast.value().contains(v1._1);
}
});
/*
* movieFilter 变为 key-value (电影ID,1),然后在进行聚合操作 变为(电影id,观看总次数),然后交换 key-value
* 变为(总次数,电影ID) 并降序排序。再次交换key-value
*/
JavaPairRDD<String, Integer> movie_count_mid = movieFilter.mapToPair(t -> new Tuple2<String, Integer>(t._2, 1)).reduceByKey((a, b) -> (a + b))
.mapToPair(t -> new Tuple2<Integer, String>(t._2, t._1)).sortByKey(false).mapToPair(t -> new Tuple2<String, Integer>(t._2, t._1));
// 打印电影名字 和喜爱人数
movie_count_mid.take(10).forEach(t -> System.out.println("喜爱人数" + t._2 + " 喜爱的电影名值" + movie_map.get(t._1) + "- "));
}
结果
喜爱人数1216 喜爱的电影名值Who's That Girl? (1987)-
喜爱人数1169 喜爱的电影名值null- #这个值不吹毛求疵了
喜爱人数1016 喜爱的电影名值Rudy (1993)-
喜爱人数990 喜爱的电影名值Gridlock'd (1997)-
喜爱人数971 喜爱的电影名值Lord of the Rings, The (1978)-
喜爱人数964 喜爱的电影名值Excess Baggage (1997)-
喜爱人数914 喜爱的电影名值First Kid (1996)-
喜爱人数903 喜爱的电影名值Absent Minded Professor, The (1961)-
喜爱人数900 喜爱的电影名值Swing Kids (1993)-
喜爱人数882 喜爱的电影名值Playing God (1997)