数据样本:第一列为people,冒号后面为对应的好友按照逗号分割
A:B,D,E,H,I,O,C
B:A,C,E,K
C:F,A,D,I
D:A,E,F,L
E:B,C,D,M,L
F:B,C,D,E,O,M
需求:求出有共同好友的所有情况 比如:A和B 的共同好友为C E那么,展示形式即为A-B:C,E
思路分析: 1.先将好友对应的People 转换格式比如:
A:B,D
转换成为如下形式
(B,List(A)) (D,List(A))
2.按照Key进行聚合得到聚合之后的结果数据
(D,List(A,B,E,G)),进行形式上面的转换为(A-B,D)(A-E,D)(A-G,D) (B-E,D) (B-G,D) (E-G,D)
3.对上述数据进行再度聚合得到:
(A-F,List(B,D,O,C,E)) 得到此种形式的数据
4.最终转换为如下形式:
(A-F,B,D,O,C,E)
代表的意思是A和F 的共同好友有B D O C E
代码实现:
import org.apache.spark.{SparkConf, SparkContext}
object CommonFriendsApp {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName(this.getClass.getSimpleName).setMaster("local[2]")
val sc = new SparkContext(conf)
sc.setLogLevel("ERROR")
val rawRdd = sc.textFile("data/friend.txt")
val matchRdd = rawRdd.flatMap(line => {
val splits = line.split(":")
val user = splits(0)
val firends = splits(1)
val friendList = firends.split(",")
val matchs = friendList.map(friend => {
(friend, List(user))
})
matchs
})
val middleResult = matchRdd.reduceByKey(_ ::: _)
middleResult.foreach(println)
val splitPair = middleResult.flatMap(pair => {
val commonFriend = pair._1
val sortedFriends = pair._2.sortBy(x => x)
val sortedFriendLength = sortedFriends.length
var commonpair: List[(String, String)] = List[(String, String)]()
for (i <- 0 until (sortedFriendLength)) {
for (j <- i + 1 until (sortedFriendLength)) {
val tmpPair = (sortedFriends(i) + "-" + sortedFriends(j), commonFriend)
commonpair = commonpair ::: List(tmpPair)
}
}
commonpair
})
splitPair.foreach(println)
splitPair.groupByKey().mapValues(values => {
values.mkString(",")
})
sc.stop()
}
}
上面是基于Spark 的方式实现求共同好友,那么基于HiveSQL的方式应该怎么实现呢?
|