【问题标题】:Extract all JSON keys提取所有 JSON 密钥
【发布时间】: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])的,而不是键。

【问题讨论】:

    标签: sql json presto


    【解决方案1】:

    你可以

    1. map_keys(cast(json_column as map<varchar,json>))提取JSON顶级键
    2. 稍后使用CROSS JOIN UNNEST“展平”密钥集合
    3. 然后您可以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) 是否有更好/更少迭代的方法来大规模实施?
    猜你喜欢
    • 2019-03-22
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多