问题描述
问题是对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
?
解决方法
为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]