如何在 Spark 2.1 中创建可以具有可选属性的类型化数据集
Posted
技术标签:
【中文标题】如何在 Spark 2.1 中创建可以具有可选属性的类型化数据集【英文标题】:How to create typed dataset which can have optional attributes in Spark 2.1 【发布时间】:2017-05-16 06:12:01 【问题描述】:我需要在 Spark 中使用数据集,它可以保存具有一些已知属性的实体,但也可以保存编译时属性的未知列表。我需要一种简单的方法来通过计算管道传递这些可选属性,而不是打扰它们。
编造代码示例:
> loaded.show
root
|-- key: long (nullable = true)
|-- value: string (nullable = true)
|-- opt1: string (nullable = true)
|-- opt2: long (nullable = true)
让我们只想象我在编译时知道和关心的键和值。
case class BusinessEntity(key: Long, value: String)
def businessLogic = this
如果我将数据框转换为类型化数据集,额外的属性显然会丢失。
loaded.as[BusinessEntity].map(_.businessLogic).toDF.printSchema
root
|-- key: long (nullable = true)
|-- value: string (nullable = true)
我需要做的是将它们存储在实体中的某个位置,以便在计算管道的最后(可以包含连接等)我能够将它们提取到目标存储。
我可以想象使用以下一些方法来存储可选数据
case class BusinessEntity(key: String, value: String, extra: Row)
dataset.select("key", "value", "row.*")
case class BusinessEntity(key: String, value: String, extra: Map[String, AnyVal])
dataset.select($"key", $"value",
/* Generate at runtime from attr list */
$"extra"("opt1").cast("long").as("opt2"),
$"extra"("opt2").cast("long").as("opt2"))
case class BusinessEntity(key: String, value: String, extra: List[AnyVal])
dataset.select($"key", $"value",
/* Generate at runtime from attr list */
$"extra"(0).cast("long").as("opt1"),
$"extra"(1).cast("long").as("opt2"))
但它们都不起作用,因为 Spark 无法为 Row/Map[?, AnyVal]/List[AnyVal] 生成编码器。到目前为止,我只能考虑将可选属性存储为 JSON 编码的字符串,但我可以将其视为最后的手段;或使用 Encoders.kryo 为 AnyVal 的 Map 生成编码器。我是否遗漏了什么并且有更简单的方法来解决此类问题?
【问题讨论】:
【参考方案1】:我只需将我的案例类中的可选值定义为Option
并将它们指定为None
作为默认值:
case class BusinessEntity(key: Long, value: String, opt1:Option[String]=None, opt2:Option[Long]=None)
【讨论】:
以上是关于如何在 Spark 2.1 中创建可以具有可选属性的类型化数据集的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Swift 中创建具有 Self 或关联类型要求的通用计算属性,如果可以,如何?
使用具有常量值的 var 在 Spark DataFrame 中创建一个新列