Spark RDD电影(根据用户年龄段)分析——广播机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012848709/article/details/85808333

楔子

Spark 分析电影
使用广播机制查找18岁喜爱的电影Top10。主要是广播机制的使用

思路

分为2部分:1 是广播 符合年龄的userid ,2是 求Top10


第一部分

  1. 过滤年龄 选取其中符合年龄的userid
  2. 上述userid 抽取到list中,广播出去

第二部分
3. 电影转为key-value (电影id,电影名) 转为map
4. 评分 转为 key-value (用户id,电影id),期间使用 第一部分的广播变量过滤符合年龄的userid
5. 上述结果 变为 key-value (电影ID,1),然后在进行聚合操作 变为(电影id,观看总次数),然后交换 key-value
6. 取Top10 查找电影名打印

demo

GitHub 位置

/**
 * 年龄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)

猜你喜欢

转载自blog.csdn.net/u012848709/article/details/85808333