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

如何从指定JSON提取data字段生成Spark DataFrame(Scala)

问题描述

我需要从如下JSON结构中提取data字段内容,转换为带指定列名的Spark DataFrame:

{
  "meta" : {},
  "data" : [ 
    [ 1, "a1", "b1" ],
    [ 2, "a2", "b2" ],
    [ 3, "a3", "b3" ]
  ]
}

我用Scala开发,当前写了如下函数:

def GetUrlContentJson(url: String): DataFrame ={
    val result = scala.io.Source.fromURL(url).mkString
    val jsonResponseOneLine = result.toString().stripLineEnd    
    val jsonRdd = spark.sparkContext.parallelize(jsonResponseOneLine :: Nil)
    val jsonDf = spark.read.json(spark.createDataset(jsonRdd))
    return jsonDf
}  

但得到的结果是:

+-------+-------+
|   data|   meta|
+-------+-------+
| [[1...|     {}|
+-------+-------+

期望得到带指定列名的结构化结果:

+----+------+------+
| id |   A  |   B  |
+----+------+------+
|  1 |   a1 |  b1  |
+----+------+------+
|  2 |   a2 |  b2  |
+----+------+------+
|  3 |   a3 |  b3  |
+----+------+------+
解决方案

方法一:使用Spark DataFrame API

先解析出data数组,将数组中的子数组展开为单独行,再拆分元素映射为指定列:

import org.apache.spark.sql.functions.{explode, col}

def GetUrlContentJson(url: String): DataFrame ={
    // 读取URL中的JSON内容并转为Dataset
    val result = scala.io.Source.fromURL(url).mkString
    val jsonDs = spark.createDataset(Seq(result))
    val jsonDf = spark.read.json(jsonDs)
    
    // 提取data数组并展开,拆分元素为指定列
    jsonDf.select(explode(col("data")).alias("data_arr"))
          .select(
              col("data_arr")(0).alias("id"),
              col("data_arr")(1).alias("A"),
              col("data_arr")(2).alias("B")
          )
}

方法二:使用Spark SQL

通过创建临时视图,用SQL语句完成提取和列映射:

def GetUrlContentJson(url: String): DataFrame ={
    val result = scala.io.Source.fromURL(url).mkString
    val jsonDs = spark.createDataset(Seq(result))
    val jsonDf = spark.read.json(jsonDs)
    
    // 创建临时视图
    jsonDf.createOrReplaceTempView("json_data")
    
    // 执行SQL转换结构
    spark.sql("""
        SELECT 
            data_arr[0] AS id,
            data_arr[1] AS A,
            data_arr[2] AS B
        FROM json_data
        LATERAL VIEW explode(data) exploded_table AS data_arr
    """)
}

补充说明

  • 必须导入explode等必要函数,避免编译错误
  • 直接将JSON字符串转为Dataset比RDD写法更简洁高效
  • 若data子数组长度固定,直接通过索引取值即可;长度不固定时可根据实际逻辑调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:57:20