在 Spark SQL 中,将 JSON 键名转换为值

Posted

技术标签:

【中文标题】在 Spark SQL 中,将 JSON 键名转换为值【英文标题】:In Spark SQL, transform JSON key name into value 【发布时间】:2021-12-21 08:29:38 【问题描述】:

在 Spark SQL 中似乎应该有一个类似于旋转的函数,但我还没有找到任何将 JSON 键转换为 a 值的解决方案。假设我有一个格式不正确的 JSON(我无法更改的格式):

"A long string containing serverA": "x": 1, "y": 2

如何处理

"server": "A", "x": 1, "y": 2

?

我将 JSON 读入 sql.dataframe,然后希望按上述方式处理它们:

val cs = spark.read.json("sample.json")
  .???

【问题讨论】:

如示例中所示,将键名直接转换为键值对是最简洁的方法,但我也可以接受类似“newkey”的内容:“包含服务器A" 【参考方案1】:

如果我们只想使用 spark 函数而不使用 UDF,您可以使用 from_json 将 json 解析为映射(我们需要指定架构)。然后,您只需要使用 spark 函数提取信息。 一种方法如下:

val schema = MapType(
    StringType,
    StructType(Array(
        StructField("x", IntegerType),
        StructField("y", IntegerType)
    ))
)

spark.read.text("...")
    .withColumn("json", from_json('value, schema))
    .withColumn("key", map_keys('json).getItem(0))
    .withColumn("value", map_values('json).getItem(0))
    .withColumn("server",
        // Extracting the server name with a regex
        regexp_replace(regexp_extract('key, "server[^ ]*", 0), "server", ""))
    .select("server", "value.*")
    .show(false)

产生:

+------+---+---+
|server|x  |y  |
+------+---+---+
|A     |1  |2  |
+------+---+---+

【讨论】:

谢谢,奥利!这将与我的玩具数据集完美配合。在我的真实数据集中,我在内部 JSON 中有更多键值映射,我想知道我是否可以在不指定架构的情况下进行转换。 使用from_json,您需要指定架构,但还有其他方法可以实现。你的 json 到底是什么样的? 它来自客户,我不确定是否可以发布整个结构。它像 "Statistics for client XXX": "ipaddress": "XX.XXX.XXX.XXX", "totalAccessRequests": 243, "totalDupAccessRequests": 0, "totalAccessAccepts": 51, 等等,有 17 个数值。我当然可以像你在这里那样写一个模式,但那时我想知道我是否走完全不同的路线(在 scala 中解析成一个案例类) 无论如何我都会接受你的回答,因为它非常适合我最初发布的玩具数据集。 谢谢,但这并不能解决您的问题 :)

以上是关于在 Spark SQL 中,将 JSON 键名转换为值的主要内容,如果未能解决你的问题,请参考以下文章

我如何将平面数据框转换为 spark(scala 或 java)中的嵌套 json

赵强老师在Spark SQL中读取JSON文件

在 Spark 中执行聚合函数时出错:ArrayType 无法转换为 org.apache.spark.sql.types.StructType

使用 pyspark 将 spark 数据帧转换为嵌套 JSON

Spark:将 JSON 文件转换为正确的格式

Spark 将 JSON 字符串转换为 JSON 对象(Java)