Apache Spark 2.1:java.lang.UnsupportedOperationException:找不到scala.collection.immutable.Set [String]的编码器

用户238607

我在Scala 2.11.6中使用Spark 2.1.1。我收到以下错误。我没有使用任何案例类。

java.lang.UnsupportedOperationException: No Encoder found for scala.collection.immutable.Set[String]
 field (class: "scala.collection.immutable.Set", name: "_2")
 field (class: "scala.Tuple2", name: "_2")
 root class: "scala.Tuple2"

以下代码部分是stacktrace指向的位置。

val tweetArrayRDD = nameDF.select("namedEnts", "text", "storylines")
    .flatMap {
    case Row(namedEnts: Traversable[(String, String)], text: String, storylines: Traversable[String]) =>
      Option(namedEnts) match {
        case Some(x: Traversable[(String, String)]) =>
          //println("In flatMap:" + x + " ~~&~~ " + text + " ~~&~~ " + storylines)
          namedEnts.map((_, (text, storylines.toSet)))
        case _ => //println("In flatMap: blahhhh")
          Traversable()
      }
    case _ => //println("In flatMap: fooooo")
      Traversable()
  }
  .rdd.aggregateByKey((Set[String](), Set[String]()))((a, b) => (a._1 + b._1, a._2 ++ b._2), (a, b) => (a._1 ++ b._1, a._2 ++ b._2))
  .map { (s: ((String, String), (Set[String], Set[String]))) => {
    //println("In map: " + s)
    (s._1, (s._2._1.toSeq, s._2._2.toSeq))
  }}
扎克·祖哈尔

这里的问题是,Spark没有提供Set开箱即用的编码器(它确实为“原始”,Seq,数组和其他受支持类型的产品提供了编码器)。

您可以尝试使用这个优秀的答案来创建你自己的编码器Set[String](准确地说是为您所使用的类型,编码器Traversable[((String, String), (String, Set[String]))]包含一个,Set[String]),或者您可以通过使用一个解决这个问题Seq,而不是一个Set

// ...
case Some(x: Traversable[(String, String)]) =>
  //println("In flatMap:" + x + " ~~&~~ " + text + " ~~&~~ " + storylines)
  namedEnts.map((_, (text, storylines.toSeq.distinct)))
// ...

(我正在distinct模仿Set行为;也可以尝试.toSet.toSeq

更新:根据您的评论,请使用Spark 1.6.2-不同之处在于,在1.6.2中,Dataset.flatMap返回anRDD而不是a Dataset,因此不需要对您提供的函数返回的结果进行编码;因此,这确实带来了另一个很好的解决方法-您可以操作之前通过显式切换为使用RDD来轻松模拟此行为flatMap

nameDF.select("namedEnts", "text", "storylines")
  .rdd
  .flatMap { /*...*/ } // use your function as-is, it can return Set[String]
  .aggregateByKey( /*...*/ )
  .map( /*...*/ )

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章