scala - 如何处理火花中缺少的嵌套字段?
问题描述
给定两个案例类:
case class Response(
responseField: String
...
items: List[Item])
case class Item(
itemField: String
...)
我正在创建一个Response
数据集:
val dataset = spark.read.format("parquet")
.load(inputPath)
.as[Response]
.map(x => x)
itemField
当任何行中不存在时,就会出现问题,并且 spark 会引发此错误org.apache.spark.sql.AnalysisException: No such struct field itemField
。如果itemField
没有嵌套,我可以通过dataset.withColumn("itemField", lit(""))
. 是否有可能在该List
领域内做同样的事情?
解决方案
我假设如下:
数据是使用以下模式编写的:
case class Item(itemField: String)
case class Response(responseField: String, items: List[Item])
Seq(Response("a", List()), Response("b", List())).toDF.write.parquet("/tmp/structTest")
现在架构更改为:
case class Item(itemField: String, newField: Int)
case class Response(responseField: String, items: List[Item])
spark.read.parquet("/tmp/structTest").as[Response].map(x => x) // Fails
对于 Spark 2.4,请参阅: Spark - 如何将元素添加到结构数组
对于 Spark 2.3,这应该有效:
val addNewField: (Array[String], Array[Int]) => Array[Item] = (itemFields, newFields) => itemFields.zip(newFields).map { case (i, n) => Item(i, n) }
val addNewFieldUdf = udf(addNewField)
spark.read.parquet("/tmp/structTest")
.withColumn("items", addNewFieldUdf(
col("items.itemField") as "itemField",
array(lit(1)) as "newField"
)).as[Response].map(x => x) // Works
推荐阅读
- python - 评估线性搜索执行速度
- r - 创建一个使用字符串和作为变量调用列的函数 - 使用基本 R 和 dplyr
- c++ - C++ 并发队列内存泄漏
- apache - Apache 反向代理中的 Google OAuth 重定向 Uri
- python - 使用python解析Javascript页面
- matlab - 为什么我在 GitHub 上的一个代码预览看起来像纯文本?
- css - Google Webfonts 破坏 CLS 分数 (FOUT)
- python - 如何在python中检查模型对象是否是Xgboost
- c# - 使用预处理器指令(符号/常量)生成docfx
- node.js - 创建 404 路由使我的所有页面都没有样式