json - Spark JSON 将 JSON 中完整的字段读取到案例类中
问题描述
考虑以下案例类模式,
case class Y (a: String, b: String)
case class X (dummy: String, b: Y)
字段 b 是可选的,我的一些数据集没有字段 b。当我尝试读取一个不包含的 JSON 字符串时,我收到一个字段丢失异常。
spark.read.json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X]
org.apache.spark.sql.AnalysisException: No such struct field b in a;
at org.apache.spark.sql.catalyst.expressions.ExtractValue$.findField(complexTypeExtractors.scala:85)
at org.apache.spark.sql.catalyst.expressions.ExtractValue$.apply(complexTypeExtractors.scala:53)
at org.apache.spark.sql.catalyst.analysis.Analyzer$$anonfun$resolveExpression$1.applyOrElse(Analyzer.scala:1074)
at org.apache.spark.sql.catalyst.analysis.Analyzer$$anonfun$resolveExpression$1.applyOrElse(Analyzer.scala:1065)
at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$2.apply(TreeNode.scala:282)
at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$transformUp$2.apply(TreeNode.scala:282)
at org.apache.spark.sql.catalyst.trees.CurrentOrigin$.withOrigin(TreeNode.scala:70)
如何自动将 JSON 中不存在的字段反序列化为 null ?
解决方案
b
将字段定义为Option
类型并使用编码器创建结构类型模式。
- 使用带有创建数据集
.schema
的选项传递定义的模式!case class X
Example:
case class Y (a: String, b: Option[String] = None)
case class X (dummy: String, b: Y)
import org.apache.spark.sql.Encoders
val schema = Encoders.product[X].schema
spark.read.schema(schema).json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X].show()
//+-----+----+
//|dummy| b|
//+-----+----+
//| 1|[1,]|
//+-----+----+
Select b column from struct type:
spark.read.schema(schema).json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X].
select("b.b").show()
//+----+
//| b|
//+----+
//|null|
//+----+
PrintSchema:
spark.read.schema(schema).json(Seq("{'dummy': '1', 'b': {'a': '1'}}").toDS).as[X].printSchema
//root
//|-- dummy: string (nullable = true)
//|-- b: struct (nullable = true)
//| |-- a: string (nullable = true)
//| |-- b: string (nullable = true)
推荐阅读
- sql - 如何解决 System.Data.DataRowView' 不包含名称为 'date' 的属性错误?
- postgresql - 如何每 5 分钟将 PostgreSQL 流复制文件复制到某个 HDD 驱动器
- c# - SimpleInjector 在使用泛型接口时注入一个空集合
- javascript - 导致组件中未定义行为的路由
- java - 垃圾回收期间何时调用 finalize()?
- laravel - 哪个文件处理 Laravel 中的重定向代码
- php - WordPress:重置密码总是无效的密钥
- c# - 执行安装在全局 nuget 缓存中的 NetCoreApp
- elasticsearch - Elasticsearch 最小聚合返回 null
- python - 如何通过 make_pipeline() 标准化训练和测试数据集