将 ADT / 密封特征层次结构编码到 Spark DataSet 列中

Posted

技术标签:

【中文标题】将 ADT / 密封特征层次结构编码到 Spark DataSet 列中【英文标题】:Encode an ADT / sealed trait hierarchy into Spark DataSet column 【发布时间】:2016-12-08 01:03:25 【问题描述】:

如果我想在 Spark DataSet 列中存储代数数据类型 (ADT)(即 Scala 密封特征层次结构),最佳编码策略是什么?

例如,如果我有一个叶类型存储不同类型数据的 ADT:

sealed trait Occupation
case object SoftwareEngineer extends Occupation
case class Wizard(level: Int) extends Occupation
case class Other(description: String) extends Occupation

什么是构建a的最佳方法:

org.apache.spark.sql.DataSet[Occupation]

【问题讨论】:

【参考方案1】:

TL;DR 目前没有好的解决方案,鉴于 Spark SQL / Dataset 的实现,在可预见的将来不太可能有。

您可以使用通用的kryojava 编码器

val occupation: Seq[Occupation] = Seq(SoftwareEngineer, Wizard(1), Other("foo"))
spark.createDataset(occupation)(org.apache.spark.sql.Encoders.kryo[Occupation])

但在实践中几乎没有用。

UDT API 目前提供了另一种可能的方法(Spark 1.62.02.1-SNAPSHOT),它是私有的,需要大量样板代码(您可以查看 o.a.s.ml.linalg.VectorUDT 以查看示例实现)。

【讨论】:

为什么 kryo 在实践中几乎没有用?是不是因为每次转换后都要指定 kryo 序列化器?【参考方案2】:

我曾经深入研究过这个主题并创建了一个 repo,展示了我发现的所有可能有用的方法。

链接:https://github.com/atais/spark-enum

一般来说,zero323 是对的,但您可能会发现了解全貌很有用。

【讨论】:

以上是关于将 ADT / 密封特征层次结构编码到 Spark DataSet 列中的主要内容,如果未能解决你的问题,请参考以下文章

Scala 中具有自定义表示的 ADT 的通用派生

用于编码/解码 arity 0 的密封特征实例的 Circe 实例?

将类型与数据构造函数相关联的 ADT 编码有啥问题? (例如斯卡拉。)

如何使用 circe 将密封特征案例对象转换为字符串

具有特征的 Spark 2.0 数据集编码器

C#之密封类(详解)