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

问题描述 投票:0回答:2

我有以下案例类:

case class Person(name: String, lastname: Option[String] = None, age: BigInt) {}

以下是json:

{ "name": "bemjamin", "age" : 1 }

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

spark.read.json("example.json")
  .as[Person].show()

它向我显示以下错误:

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

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

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

scala apache-spark apache-spark-sql apache-spark-dataset
2个回答
3
投票

我们还有一个选项来解决上述问题。需要两个步骤

  1. 确保可以丢失的字段声明为可空的Scala类型(如Option [_])。
  2. 提供架构参数而不依赖于架构推断。您可以使用例如使用Spark SQL编码器: import org.apache.spark.sql.Encoders val schema = Encoders.product[Person].schema

您可以更新代码,如下所示。

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|
+--------+--------+---+

1
投票

当你执行spark.read.json("example.json").as[Person].show()时,它基本上是在读取数据帧,

FileScan json [age#6L,name#7]

然后尝试为Person对象应用编码器,从而获得AnalysisException,因为它无法从您的json文件中找到lastname

您可以通过提供一些具有姓氏的数据来提示spark lastname是可选的,或者尝试这样做:

val schema: StructType = ScalaReflection.schemaFor[Person].dataType.asInstanceOf[StructType]
val x = spark.read
      .schema(schema)
      .json("src/main/resources/json/x.json")
      .as[Person]
+--------+--------+---+
|    name|lastname|age|
+--------+--------+---+
|bemjamin|    null|  1|
+--------+--------+---+

希望能帮助到你。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.