如何在Spark Dataset中存储嵌套的自定义对象?

问题是对How to store custom objects in Dataset?的跟进

火花版本:3.0.1

可以实现非嵌套的自定义类型:

5.66002e-320 2.31834e-316
1.132e-316 4.63669e-313
1.698e-319 6.95503e-316
1.132e-316 4.63669e-313
5.66002e-320 2.31834e-316
1.132e-316 4.63669e-313
1.698e-319 6.95503e-316
1.132e-316 4.63669e-313
5.66002e-320 2.31834e-316
1.132e-316 4.63669e-313
1.698e-319 6.95503e-316
1.132e-316 4.63669e-313

但是,如果自定义类型在import spark.implicits._ import org.apache.spark.sql.{Encoder,Encoders} class AnObj(val a: Int,val b: String) implicit val myEncoder: Encoder[AnObj] = Encoders.kryo[AnObj] val d = spark.createDataset(Seq(new AnObj(1,"a"))) d.printSchema root |-- value: binary (nullable = true) 类型(即product)内是嵌套,则会出现错误:

java.lang.UnsupportedOperationException:未找到InnerObj的编码器

case class

如何创建具有嵌套自定义类型的import spark.implicits._ import org.apache.spark.sql.{Encoder,Encoders} class InnerObj(val a: Int,val b: String) case class myobj(val i: Int,val j: InnerObj) implicit val myEncoder: Encoder[InnerObj] = Encoders.kryo[InnerObj] // error val d = spark.createDataset(Seq(new myobj(1,new InnerObj(0,"a")))) // it gives Runtime error: java.lang.UnsupportedOperationException: No Encoder found for InnerObj

zhangzhuhui 回答:如何在Spark Dataset中存储嵌套的自定义对象?

为MyObj和InnerObj添加编码器应该可以使其工作。

  class InnerObj(val a:Int,val b: String)
  case class MyObj(val i: Int,j: InnerObj)

  implicit val myEncoder: Encoder[InnerObj] = Encoders.kryo[InnerObj]
  implicit val objEncoder: Encoder[MyObj] = Encoders.kryo[MyObj]

上面的代码片段可以编译并正常运行

,

除了sujesh之外的另一种解决方案:

import spark.implicits._
import org.apache.spark.sql.{Encoder,Encoders}

class InnerObj(val a: Int,val b: String)
case class MyObj[T](val i: Int,val j: T)

implicit val myEncoder: Encoder[MyObj[InnerObj]] = Encoders.kryo[MyObj[InnerObj]] 

// works
val d = spark.createDataset(Seq(new MyObj(1,new InnerObj(0,"a"))))

这也显示出可以从type parameter推断出内部类型的情况与不能推断出内部类型的情况之间的区别。

前一种情况应该做:

implicit val myEncoder: Encoder[MyObj[InnerObj]] = Encoders.kryo[MyObj[InnerObj]]

以后的情况应该做:

implicit val myEncoder1: Encoder[InnerObj] = Encoders.kryo[InnerObj]
implicit val myEncoder2: Encoder[MyObj] = Encoders.kryo[MyObj]
本文链接:https://www.f2er.com/1457619.html

大家都在问