【问题标题】:How to explode a JSON array in Apache Spark [duplicate]如何在 Apache Spark 中分解 JSON 数组 [重复]
【发布时间】:2019-02-21 14:26:41
【问题描述】:

给定一个包含 JSON 数组的列的 spark 2.3 DataFrame,我如何将它们转换为 JSON 字符串的 Spark 数组?或者,等效地,我怎样才能分解 JSON,以便输入:

myJsonColumn
"""[{"a":1},{"b":2}]"""
"""[{"c":3},{"d":4}]"""
"""[{"e":3},{"f":4},{"g":{"h":1}}]"""

我明白了:

myExplodedJson
"""{"a":1}"""
"""{"b":2}"""
"""{"c":3}"""
"""{"d":4}"""
"""{"e":3}"""
"""{"f":4}"""
"""{"g":{"h":1}}"""

非常感谢!

附言数组中条目的形状是可变的。

这是一个示例输入,以防有用:

List("""[{"a":1},{"b":2}]""", """[{"c":3},{"d":4}]""", """[{"e":3},{"f":4},{"g":{"h":1}}]""").toDF.show

p.p.s.这与迄今为止所有建议的重复问题不同。问题和解决方案,例如How to query JSON data column using Spark DataFrames? 适用于 (1) 数据全部为 JSON 数据时,因此可以将整个数据帧作为 JSON 读入。这不适用于这个问题,例如数据可以是包含 JSON 字符串的单列的 CSV。这也与查询是查找特定键的情况不同,get_json_object 确实涵盖了这一点。它也不同于数组中元素数量有界的情况,因此仅查找前 100 个(例如,数组索引)然后丢弃空值可能是可以接受的,但即便如此,仅当数组中没有空值时才适用原始 JSON 数组。

p.p.s.需要的是类似 postgres 中的 json_array_elements 的东西。我的后盾是编写一个接受 JSON 字符串并返回 spark 数组的 UDF,但 UDF 往往比内置函数慢,并且爆炸式 JSON 可能在核心 Spark 功能中。为什么要重新发明基础?

【问题讨论】:

  • 你想要什么输出 {"g":{"h":1}?
  • @Michael 请提供 JSON 序列化。 g:{h 示例是为了强调模式不是恒定的。 :-)。键随其他键更改,但仍可以表示为地图。每个输入都是一个未指定内容的 JSON 数组。相应的输出应该是编码“东西”的火花数组。
  • @Michael 谢谢你的链接。我已经阅读了这两本书,但都没有解决问题。我已经问过 Tzach 是否有任何更新,以防他知道最近的功能启用了更好的方法。

标签: apache-spark apache-spark-sql


【解决方案1】:

您可以将explodearray 函数一起使用。

在 Spark 2.3.1 中,您可以这样做 -

val df = List("""[{"a":1},{"b":2}]""", """[{"c":3},{"d":4}]""", """[{"e":3},{"f":4},{"g":{"h":1}}]""").toDF

df.withColumn("value", explode(array(
  get_json_object($"value", "$[0]"),
  get_json_object($"value", "$[1]")
))).show

这个的输出是 -

+-------+
|  value|
+-------+
|{"a":1}|
|{"b":2}|
|{"c":3}|
|{"d":4}|
|{"e":3}|
|{"f":4}|
+-------+

【讨论】:

  • 如果每个数组中的元素数量总是相同,那就太好了。当元素数量可变时怎么办?有一种蛮力方法——只获取前 100 个,希望永远不会超过 100 个,然后过滤掉空值——但这有很多缺点。
  • @MaxMurphy 你的数据总是有单键 json 吗?类似 - "[{"a":1},{"b":2},{"p":5}, .... ] ?
  • 没有。数组元素的结构是可变的。
猜你喜欢
  • 1970-01-01
  • 2017-03-24
  • 2017-11-10
  • 2017-04-14
  • 1970-01-01
  • 2017-05-12
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多