Spark SQL 不支持 JSONPATH 通配符的任何解决方法

问题描述 投票:0回答:2
spark.sql("""select get_json_object('{"k":{"value":"abc"}}', '$.*.value') as j""").show()

这会导致 null,而它应该返回“abc”。如果我用

*
替换
k
就可以了。

我知道 JSONPath 支持有限(https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-get_json_object

但是有没有办法实现这一点,那就是 Spark SQL。

scala apache-spark apache-spark-sql
2个回答
2
投票

有一个 Spark JIRA“任何在 get_json_object ($..foo) 中不起作用的深度搜索”开放以获取完整的 JsonPath 支持。

在问题得到解决之前,恐怕创建一个使用“通用”JsonPath 实现的 UDF 可能是唯一的选择:

> spark-shell --jars "json-path-2.7.0.jar"                      
:
scala> import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.JsonPath

scala> val r = JsonPath.read[net.minidev.json.JSONArray]("""
     | {"k":{"value":"abc"},
     |  "m":{"value":"def"}}
     | ""","$.*.value")
r: net.minidev.json.JSONArray = ["abc","def"]

scala> 

0
投票

这是一个迟到的答案,但可能对未来的访客有用。在撰写本文时,Spark 对 JsonPath 的支持仍然有限,这意味着我们仍然需要一种解决方法。我正在使用 pyspark,但该解决方案应该适用于任何地方。

Spark 中的

get_json_object
无法通过通配符解析键值,但我们可以尝试利用
from_json
函数来创建字符串和其他映射或数组的 MAP
fn.explode(fn.from_json('value', 'MAP<STRING,MAP<STRING, STRING>>'))

与explode一起,您可以将映射解压缩为单独的键列和值列。这是用于测试的片段:

spark.sql("""
select explode(from_json('{"k": {"value":"abc"}}', 'MAP<STRING,MAP<STRING, STRING>>'))
""").show()

Output:
+---+--------------+
|key|         value|
+---+--------------+
|  k|{value -> abc}|
+---+--------------+
© www.soinside.com 2019 - 2024. All rights reserved.