Scala Spark 地图类型匹配问题

Posted

技术标签:

【中文标题】Scala Spark 地图类型匹配问题【英文标题】:Scala Spark map type matching issue 【发布时间】:2016-09-19 21:40:30 【问题描述】:

我正在尝试使用 Scala 对日志数据执行一系列转换,但在匹配元组时遇到了困难。我有一个包含用户 ID、网址和日期的数据框。我可以将数据框映射到 RDD 并使用此映射键减少:

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), count):

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)

我已经尝试了这两个具有显式和隐式类型的 map 调用的许多不同排列,这似乎让我走得最远。我希望这里有人可以帮助我指出正确的方向。

【问题讨论】:

【参考方案1】:

这样的事情应该可以工作:

countsRDD
  .map case ((user_id, url), count) => (url, (user_id, count)) 
  .groupByKey
countsRDDRDD[((String, String), Int)] 不是 RDD[Row]。 无需使用TupleN。元组文字可以正常工作。 由于countsRDD 是静态类型的(与RDD[Row] 不同),您不必指定类型。 不要使用reduceByKey 进行列表连接。这是您可以采取的最糟糕的方法,并且忽略了计算复杂性、垃圾收集器和常识如果您确实需要专为此设计的分组数据使用操作。

【讨论】:

以上是关于Scala Spark 地图类型匹配问题的主要内容,如果未能解决你的问题,请参考以下文章

Scala、Array[Int] 和 Array[Option[Int]] 中的类型不匹配

Spark记录-Scala模式匹配

类型不匹配;找到:org.apache.spark.sql.DataFrame 需要:org.apache.spark.rdd.RDD

模式匹配开销?

字符串列包含通过 spark scala 精确匹配的单词

Scala实战高手****第13课Scala模式匹配实战和Spark源码鉴赏