Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache Spark 2.1:java.lang.UnsupportedOperationException:找不到scala.collection.immutable.Set[String]的编码器_Scala_Apache Spark_Apache Spark Encoders - Fatal编程技术网

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

Apache Spark 2.1:java.lang.UnsupportedOperationException:找不到scala.collection.immutable.Set[String]的编码器,scala,apache-spark,apache-spark-encoders,Scala,Apache Spark,Apache Spark Encoders,我将Spark 2.1.1与Scala 2.11.6结合使用。我得到以下错误。我没有使用任何case类 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:

我将Spark 2.1.1与Scala 2.11.6结合使用。我得到以下错误。我没有使用任何case类

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]
),您可以通过使用
序列而不是
集合来解决此问题:

// ...
case Some(x: Traversable[(String, String)]) =>
  //println("In flatMap:" + x + " ~~&~~ " + text + " ~~&~~ " + storylines)
  namedEnts.map((_, (text, storylines.toSeq.distinct)))
// ...
(我正在使用
distinct
来模拟
设置
行为;也可以尝试
.toSet.toSeq

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

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

谢谢你的回答。我想知道为什么Spark 1.6.2中没有出现这个问题?我知道这与编码器在2.0中是强制性的有关。但是,如果spark 1.6.2可以正常工作,为什么2.0就不能这样呢?