Spark数据集联合重置类变量

时间:2017-05-09 13:22:03

标签: scala apache-spark apache-spark-dataset

我有这样的案例类:




 案例类Ais(NotImportant)
扩展Serializable {


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

 override def toString():String = {
的 “$集群,$标记,$走访” 
 }
}
  




运行我的算法后,我最终得到两个类型为的数据集(Int,Ais) )其中 Ais 对象中的变量包含信息。我需要结合它们。对我来说最重要的是 var cluster var visited 的值。然而在 union 之后,它们被重置为默认值。




  labeledInner.foreach(println(_))//这很好&# xA; println(“==========”)
 labeledOuter.foreach(println(_))//这也很好
 println(“======== ==“)
 labeledOuter.union(labeledInner).foreach(println(_))// Here
 //一切都设置为默认
  




我正在运行Spark 2.1和Scala 2.11.8。




1 个答案:

答案 0 :(得分:4)

在使用Spark时,你不应该在case类中使用mutable vars - 这些不能“存活”Spark的编码,所以任何非常重要的数据集使用(比如使用{{触发编码和解码的1}})不会保留这些字段。

<强>为什么? Spark内置了编码器,可以有效地将对象编码为字节数组(以及后面的数组)。对于案例类(实际上,对于所有union,主要是案例类和元组),编码器只编码案例类字段,它们被定义为类参数(在您的情况下) , 只有1个}})。您可以通过为案例类创建相关编码器并检查其架构

来查看此内容
Product

如您所见 - 只有NotImportant幸存,case class A(s: String) { var a: Int = 0 } Encoders.product[A].schema.printTreeString() // root // |-- s: string (nullable = true) 不属于架构。

有什么选择?使用Spark(实际上是Scala)时,你应该避免使用 mutable 字段。尝试对数据建模以将所有字段包含为不可变字段,例如:

s

然后,为了“改变”这些对象,您可以使用创建新实例的a方法,其中一些(或没有)字段已更改,例如:

case class Ais(flag: Flag, cluster: Cluster, visited: Boolean)

这些对象可以安全地与Spark一起使用(它们“存活”序列化并且是不可变的。)