2016-09-19 263 views
0

我想用Scala對日誌數據執行一系列轉換,而且我在匹配元組時遇到了困難。我有一個數據框與用戶ID,網址和日期。我可以將數據幀映射到RDD以及主要與此映射減少:Scala Spark映射類型匹配問題

val countsRDD = usersUrlsDays.map { case Row(date:java.sql.Date, user_id:Long, url:String) => Tuple2(Tuple2(user_id, url), 1) }.rdd.reduceByKey(_+_) 

這讓我的RDD((USER_ID,URL),計數):

scala> countsRDD.take(1) 
res9: Array[((Long, String), Int)]  
scala> countsRDD.take(1)(0) 
res10: ((Long, String), Int) 

現在我想反轉通過URL來獲得:

(url, [(user_id, count), ...]) 

我已經試過這樣:

val urlIndex = countsRDD.map{ case Row(((user_id:Long, url:String), count:Int)) => Tuple2(url, List(Tuple2(user_id, count))) }.reduceByKey(_++_) 

這將產生匹配誤差,但是:

scala.MatchError: ... (of class scala.Tuple2) 

我已經試過這兩個地圖明確和隱含的類型,這似乎呼籲已經得到了我最遠的很多很多不同的排列。我希望有人能幫助我指出正確的方向。

回答

2

像這樣的東西應該工作:

countsRDD 
    .map{ case ((user_id, url), count) => (url, (user_id, count)) } 
    .groupByKey 
  • countsRDDRDD[((String, String), Int)]RDD[Row]
  • 沒有必要使用TupleN。元組文字可以正常工作。
  • 由於countsRDD是靜態類型的(不像RDD[Row]),您不必指定類型。
  • 請勿使用reduceByKey進行列表連接。這是你可以採取的最糟糕的方法,並忽略計算複雜性,垃圾收集器和常識。 如果您真的需要分組數據使用操作是專爲它設計的。