簡體   English   中英

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

[英]Apache Spark 2.1 : java.lang.UnsupportedOperationException: No Encoder found for scala.collection.immutable.Set[String]

我在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))
  }}

這里的問題是,星火沒有為提供編碼器Set外的開箱(它的“原型”提供編碼器,Seqs,數組和其他支持的類型的產品)。

您可以嘗試使用這個出色的答案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

更新 :根據您的評論,請Dataset.flatMap Spark Dataset.flatMap區別在於1.6.2中, Dataset.flatMap返回RDD而不是Dataset ,因此不需要對您提供的函數返回的結果進行編碼; 因此,這確實帶來了另一個很好的解決方法-您可以通過在flatMap操作之前顯式切換為使用RDD來輕松模擬此行為:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM