提取所有 JSON 密钥

Posted

技术标签:

【中文标题】提取所有 JSON 密钥【英文标题】:Extract all JSON keys 【发布时间】:2018-05-15 05:53:21 【问题描述】:

我有一个 JSON 列 j 喜欢:

'a': 2, 'b': 'b1': 3, 'b2': 5
'c': 3, 'a': 5
'd': 1, 'c': 7

如何从 Presto 获取所有不同的(***)键名? IE。我有点像

select distinct foo(j)

返回

['a', 'b', 'c', 'd']

(请注意,在这种情况下,我不太关心嵌套键)

Presto documentation 没有任何明确符合要求的功能。唯一看起来很接近的是提到JSONPath 语法,但即使这似乎也不准确。以下至少一项应该返回 something 但对我来说在 Presto 中都失败了:

select json_extract(j, '$.*')
select json_extract(j, '$..*')
select json_extract(j, '$[*]')
select json_extract(j, '*')
select json_extract(j, '..*')
select json_extract(j, '$*.*')

此外,我怀疑这将返回来自j(即[2, 3, 5, 3, 5, 1, 7])的,而不是键。

【问题讨论】:

【参考方案1】:

你可以

    map_keys(cast(json_column as map<varchar,json>))提取JSON***键 稍后使用CROSS JOIN UNNEST“展平”密钥集合 然后您可以SELECT DISTINCT 获取不同的***密钥。

将这些放在一起的示例:

presto> SELECT DISTINCT m.key
     -> FROM (VALUES JSON '"a": 2, "b": "b1": 3, "b2": 5', JSON '"c": 3, "a": 5')
     ->     example_table(json_column)
     -> CROSS JOIN UNNEST (map_keys(CAST(json_column AS map<varchar,json>))) AS m(key);
 key
-----
 a
 b
 c
(3 rows)

【讨论】:

一项附加条件是,如果您的列存储为 varchar(如 '"a": 2, "b": "b1": 3, "b2": 5'),则您需要使用 json_parse(json_column) 转换为 JSONnot @ 987654330@ 没有CROSS JOIN 有没有办法做到这一点?在超过 10 亿行的数据库上,这非常慢。 我现在的方法是:放大到我可以执行的足够小的数据子集(大约 700 万行,我在其中找到了 36 个唯一键);然后将where not key in (keys_found_from_narrow_query) 子句添加到更广泛的查询中。 1) 这实际上是在整个数据集中查找唯一键的更好方法吗 2) 是否有更好/更少迭代的方法来大规模实施?

以上是关于提取所有 JSON 密钥的主要内容,如果未能解决你的问题,请参考以下文章

从 JSON 响应中提取浮点密钥对值时出现 TypeError

Redshift - 使用 Python UDF 从 JSON 中提取根密钥

如何使用 xcode 提取或解压缩 json 密钥(来自 API)?

JSON 子级别提取 - 如何? Objective-C

如何从 json 对象中获取密钥

无法从颤振中的 jsonDecoded 变量中提取密钥