Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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
Scala Spark数据集联合重置类变量_Scala_Apache Spark_Apache Spark Dataset - Fatal编程技术网

Scala Spark数据集联合重置类变量

Scala Spark数据集联合重置类变量,scala,apache-spark,apache-spark-dataset,Scala,Apache Spark,Apache Spark Dataset,我有这样的案例课: case class Ais(NotImportant) extends Serializable { var flag = Ais.Flag.NotFlagged var cluster = Ais.Unknown var visited = false override def toString(): String = { s"$cluster,$flag,$visited" } } 在运行我的算法之后,我得到了两个Int类型的数据

我有这样的案例课:

case class Ais(NotImportant)
  extends Serializable {


  var flag = Ais.Flag.NotFlagged
  var cluster = Ais.Unknown
  var visited = false

  override def toString(): String = {
    s"$cluster,$flag,$visited"
  }
}
在运行我的算法之后,我得到了两个Int类型的数据集,Ais对象中的变量包含信息。我需要把他们联合起来。对我来说最重要的是var cluster和var visited的值。但在联合之后,它们被重置为默认值

labeledInner.foreach(println(_)) // This is fine
println("==========")
labeledOuter.foreach(println(_)) // This is also fine
println("==========")
labeledOuter.union(labeledInner).foreach(println(_)) // Here 
                                                // everything set to default

我正在运行Spark 2.1和Scala 2.11.8。

在使用Spark时,不应该在case类中使用可变变量-这些变量在Spark的编码中无法生存,因此任何非平凡的数据集使用,如使用union触发编码和解码,都不会保留这些字段

为什么??Spark具有内置编码器,用于高效地将对象编码到字节数组中并返回。对于case类,实际上,对于所有产品(主要指case类和元组),编码器只对case类字段进行编码,这些字段在您的case中定义为类参数,只是不重要。通过为您的案例类创建相关编码器并检查其模式,您可以看到这一点:

正如您所看到的,只有s幸存下来,a不是模式的一部分

替代方案是什么?一般来说,在使用Spark和Scala时,应该避免使用可变字段。尝试将数据建模为包含所有字段的不可变字段,例如:

case class Ais(flag: Flag, cluster: Cluster, visited: Boolean)
然后,要改变这些对象,您可以使用copy方法创建一个新实例,其中部分字段或任何字段都没有更改,例如:

val a = Ais(Ais.Flag.NotFlagged, Ais.Unknown, false)
val b = a.copy(visited = true)

这些对象可以安全地与Spark一起使用,它们在序列化后仍然存在,并且是不可变的。

谢谢,这证实了我的怀疑。有没有办法用其他编码器(比如kryo)来保存可变变量的状态?
val a = Ais(Ais.Flag.NotFlagged, Ais.Unknown, false)
val b = a.copy(visited = true)