You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark DataFrame含嵌套键JSON字符串处理:如何拆解嵌套数组为多行提取字段值?

Spark JSON嵌套数组Explode提取字段实现

原有方案问题

使用get_json_object提取的nestedKey是JSON格式字符串,并非Spark可直接操作的数组结构,无法直接执行explode炸裂,需先将其转换为Spark内置Array类型后再处理。

实现步骤

  • 定义nestedKey对应的数组结构Schema,兼容数组内每个元素的字段类型
  • 用from_json函数将提取到的nestedKey字符串转换为Spark内置Array类型
  • 调用explode将数组炸裂为多行,非数组行可按需选择保留或过滤
  • 从炸裂后的Struct字段中提取目标取值

完整可运行代码

// 导入所需函数与类型
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
import spark.implicits._

val df = Seq(
  ("1", """{"k": "foo", "v": 1.0}""", "some_other_field_1"),
  ("2", """{"p": "bar", "q": 3.0}""", "some_other_field_2"),
  ("3",
    """{"nestedKey":[ {"field name":"name1","Value1":false,"Value2":true},
      |                 {"field name":"name2","Value1":"100","Value2":"200"}
      |]}""".stripMargin, "some_other_field_3")
).toDF("id","json","other")

// 定义nestedKey对应的数组Schema:数组元素为包含3个字段的Struct
val nestedSchema = ArrayType(
  StructType(Seq(
    StructField("field name", StringType), // 字段名含空格,引用时需加反引号
    StructField("Value1", StringType),
    StructField("Value2", StringType)
  ))
)

val finalDF = df
  .select(
    col("id").as("id1"),
    col("other").as("other1"),
    get_json_object(col("json"), "$.k").as("k"),
    get_json_object(col("json"), "$.v").as("v"),
    get_json_object(col("json"), "$.p").as("p"),
    get_json_object(col("json"), "$.q").as("q"),
    // 先提取nestedKey的JSON字符串,再转换为Array结构
    from_json(get_json_object(col("json"), "$.nestedKey"), nestedSchema).as("nestedArr")
  )
  // 若需保留nestedArr为null的行,可将explode替换为explode_outer
  .withColumn("nestedItem", explode(col("nestedArr")))
  .select(
    "id1", "other1", "k", "v", "p", "q",
    col("nestedItem.`field name`").as("field_name"),
    col("nestedItem.Value1"),
    col("nestedItem.Value2")
  )

finalDF.show(truncate = false)

输出结果

+----+-----------------+----+----+----+----+----------+-------+-------+
|id1 |other1           |k   |v   |p   |q   |field_name|Value1 |Value2 |
+----+-----------------+----+----+----+----+----------+-------+-------+
|1   |some_other_field_1|foo |1.0 |null|null|null      |null   |null   |
|2   |some_other_field_2|null|null|bar |3.0 |null      |null   |null   |
|3   |some_other_field_3|null|null|null|null|name1     |false  |true   |
|3   |some_other_field_3|null|null|null|null|name2     |100    |200    |
+----+-----------------+----+----+----+----+----------+-------+-------+

注意事项

  • 字段名含空格的field name,Spark引用时必须加反引号`,否则会触发解析报错
  • Value1、Value2的类型可根据实际业务调整Schema定义,示例中统一用StringType兼容布尔、字符串两种取值,也可按需转换为对应数值/布尔类型
  • 若需要保留nestedArr为null的行(避免id为1、2的行因无嵌套数组被过滤),可将explode替换为explode_outer

内容的提问来源于stack exchange,提问作者CoolGoose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 20:24:00