spark 使用带有选项字段的案例类将数据帧转换为数据集

Bem*_*ino 5 scala apache-spark apache-spark-sql apache-spark-dataset

我有以下案例类:

case class Person(name: String, lastname: Option[String] = None, age: BigInt) {}
Run Code Online (Sandbox Code Playgroud)

以及以下 json:

{ "name": "bemjamin", "age" : 1 }
Run Code Online (Sandbox Code Playgroud)

当我尝试将数据框转换为数据集时:

spark.read.json("example.json")
  .as[Person].show()
Run Code Online (Sandbox Code Playgroud)

它向我显示以下错误:

线程“main”org.apache.spark.sql.AnalysisException 中的异常:无法解析lastname给定的输入列“ ”:[年龄,名称];

我的问题是:如果我的架构是我的案例类并且它定义姓氏是可选的,那么 as() 不应该进行转换吗?

我可以使用 .map 轻松解决此问题,但我想知道是否有另一种更清洁的替代方法。

KZa*_*gol 7

我们还有另一种选择来解决上述问题。需要 2 个步骤

  1. 确保可能缺失的字段被声明为可为空的 Scala 类型(如 Option[_])。

  2. 提供架构参数而不依赖于架构推断。例如,您可以使用Spark SQL Encoder

    import org.apache.spark.sql.Encoders
    
    val schema = Encoders.product[Person].schema
    
    Run Code Online (Sandbox Code Playgroud)

您可以按如下方式更新代码。

val schema = Encoders.product[Person].schema

val df = spark.read
           .schema(schema)
           .json("/Users/../Desktop/example.json")
           .as[Person]

+--------+--------+---+
|    name|lastname|age|
+--------+--------+---+
|bemjamin|    null|  1|
+--------+--------+---+
Run Code Online (Sandbox Code Playgroud)