使用带有选项字段的情况类别类别的情况类,可以将数据帧转换为数据集



我有以下案例类:

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.sql.analysisexception中的例外: 无法解析" lastname"给定输入列:[年龄,名称];

我的问题是:如果我的架构是我的案例类,并且它定义了最后一个名称是可选的,那么as()是否应该转换?

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

我们还有一个可以解决的选项。需要2个步骤

  1. 确保可能缺少的字段被声明为无效Scala类型(例如选项[_])。

  2. 提供一个架构参数,而不依赖于模式推理。

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

当您执行spark.read.json("example.json").as[Person].show()时,它基本上是读取dataframe as,

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

,然后尝试将编码器应用于人对象,因此获得分析感,因为它无法从JSON文件中找到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|
+--------+--------+---+

希望它有帮助。

相关内容

  • 没有找到相关文章

最新更新