思路: 生成用户不同时间访问不同网站的数据,计算出pv 、uv
pv 页面访一次加1 ,uv 不同用户访问 加1
//ip
val IP = 223
//地址
val ADDRESS = Array("北京", "天津", "上海", "重庆", "河北", "辽宁","山西",
"吉林", "江苏", "浙江", "黑龙江", "安徽", "福建", "江西",
"山东", "河南", "湖北", "湖南", "广东", "海南", "四川",
"贵州", "云南", "山西", "甘肃", "青海", "台湾", "内蒙",
"广西", "西藏", "宁夏", "新疆", "香港", "澳门")
//日期
val DATE = new SimpleDateFormat("yyyy-MM-dd").format(new Date())
//timestamp
val TIMESTAMP = 0L
//userid
val USERID = 0L
//网站
val WEBSITE = Array("www.baidu.com", "www.taobao.com", "www.dangdang.com", "www.jd.com", "www.suning.com", "www.mi.com", "www.gome.com.cn")
//行为
val ACTION = Array("Regist", "Comment", "View", "Login", "Buy", "Click", "Logout")
生成数据格式为: (数据生成程序在文末)
106.76.45.38 广东 2019-11-25 1574697285759 1202189129021276418 www.gome.com.cn Login
开始代码编写
val conf = new SparkConf()
conf.setMaster("local")
conf.setAppName("test")
val sc = new SparkContext(conf)
问题一、
求每个网址的top3 访问地区
这里教程里面的思路是这样
//每个网址的每个地区访问量 ,由大到小排序
val site_local = lines.map(line=>{(line.split("\t")(5),line.split("\t")(1))})
// 网址为key 将地区作为 iterable , 然后遍历 iterable 。统计 iterable 中地区的数目 。
val site_localIterable = site_local.groupByKey()
val result = site_localIterable.map(one => {
val localMap = mutable.Map[String, Int]()
val site = one._1
val localIter = one._2.iterator
// 统计 iterable 中地区的数目 。 放置到local map 中 地区 数量
while (localIter.hasNext) {
val local = localIter.next()
if (localMap.contains(local)) {
val value = localMap.get(local).get
localMap.put(local, value + 1)
} else {
localMap.put(local, 1)
}
}
//取出前三个 地区及对应的 数量,这里教程中的代码没加 -号,则是从小到大排序
val tuples: List[(String, Int)] = localMap.toList.sortBy(one => {
-one._2
})
//封装到 对应的 site 返回结果中
if(tuples.size>3){
val returnList = new ListBuffer[(String, Int)]()
for(i <- 0 to 2){
returnList.append(tuples(i))
}
(site, returnList)
}else{
(site, tuples)
}
})
result.foreach(println)
我自己实现的思路是:
//每个网址,地区访问量的top3 及访问量
val site_local_a=lines.map(line=>{
val item=line.split("\t")
(item(5)+"_"+item(1),1)
}
)
//返回 网址 地区 的tuple
// val site_local_result = site_local_a.reduceByKey((a:Int,b:Int)=>{a+b})
val site_local_result = site_local_a.reduceByKey(_+_)
val local_result=site_local_result.map(line=>{
val site_local=line._1.split("_")
(site_local(0),(site_local(1),line._2))
}).groupByKey().map(line=>{
val site=line._1
val tuples=line._2.iterator.toList.sortBy(elem=> -elem._2).take(3)
(site,tuples)
}).foreach(println)
两者的结果是一样的。 思路不同。具体可以看代码中的注释。
问题二、 pv
lines.map(line=>{(line.split("\t")(5),1)}).reduceByKey((v1:Int,v2:Int)=>{
v1+v2
}).sortBy(tp=>{tp._2},false).foreach(println)
问题 三 、 uv
lines.map(line=>{line.split("\t")(0)+"_"+line.split("\t")(5)})
.distinct() //去重
.map(one=>{(one.split("_")(1),1)})
.reduceByKey(_+_)
.sortBy(_._2,false)
.foreach(println)
以上是自己的一点总结,包括实现的思路,如果有更好的方法。多多指教。谢谢!