目录
广告点击Top3
数据格式
思路分析
package com.xcu.bigdata.spark.core.pg02_topn
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* @Desc : 基于SparkCore的topn(统计每一个省份广告点击排名前3的)
*/
object Spark01_TopN {
def main(args: Array[String]): Unit = {
//创建配置文件
val conf: SparkConf = new SparkConf().setAppName("Spark01_TopN").setMaster("local[*]")
//创建SparkContext,该对象是提交的入口
val sc = new SparkContext(conf)
//创建RDD(时间戳 省份id 城市id 用户id 广告id)
val rdd: RDD[String] = sc.textFile("./input/agent.log")
//对读取到的数据,进行结构转换(省份id-广告id, 1)
val mapRDD: RDD[(String, Int)] = rdd.map {
line => {
//当前行的字符串进行切分
val fileds: Array[String] = line.split(" ")
//封装为元组结构返回
(fileds(1) + "-" + fileds(4), 1)
}
}
//对当前省份的每一个广告点击次数进行聚合(省份A-广告A, 988),(省份A-广告B, 777)
val reduceByKyeRDD: RDD[(String, Int)] = mapRDD.reduceByKey(_ + _)
//再次对结构进行转换,将省份作为key,(省份A,(广告A, 988))
val mapRDD1: RDD[(String, (String, Int))] = reduceByKyeRDD.map {
case (proAndAD, clickCount) => {
val proAndAdArr: Array[String] = proAndAD.split("-")
//封装为元组结构返回
(proAndAdArr(0), (proAndAdArr(1), clickCount))
}
}
//按照省份对数据进行分组 (省份, Iterable[(广告A, 80),(广告B, 100),(广告C, 90),(广告D, 200)....])
val groupRDD: RDD[(String, Iterable[(String, Int)])] = mapRDD1.groupByKey()
//对每一个省份中的广告点击次数进行降序排序,并取前3名
val resRDD: RDD[(String, List[(String, Int)])] = groupRDD.mapValues(
iter => { // iter.toList : List((广告A, 80),(广告B, 100),(广告C, 90),(广告D, 200))
iter.toList.sortWith { // iter.toList.sortWith : List((广告A, 80),(广告B, 100))
(left, right) => {
left._2 > right._2
}
}.take(3)
}
)
//打印输出
resRDD.collect().foreach(println)
//释放资源
sc.stop()
}
}
输出:
(8,List((2,27), (20,23), (11,22)))
(4,List((12,25), (16,22), (2,22)))
(6,List((16,23), (24,21), (27,20)))
(0,List((2,29), (24,25), (26,24)))
(2,List((6,24), (21,23), (29,20)))
(7,List((16,26), (26,25), (1,23)))
(5,List((14,26), (21,21), (12,21)))
(9,List((1,31), (28,21), (0,20)))
(3,List((14,28), (28,27), (22,25)))
(1,List((3,25), (6,23), (5,22)))