使用随机键字段提取复杂的 json

Extract complex json with random key field

我正在尝试将以下 JSON 提取到它自己的行中,例如 Presto 查询中下面的 table。这里的问题是 key/av 引擎名称的名称对于每一行都是不同的,我坚持如何在不知道键的值的情况下提取和迭代键。

json 是 table 行的值

{
    "Bkav":
    {
        "detected": false,
        "result": null,
    },
    "Lionic":
    {
        "detected": true,
        "result": Trojan.Generic.3611249',
    },
    ...
AV Engine Name Detected Virus Result
Bkav false null
Lionic true Trojan.Generic.3611249

我尝试按照此处的文档使用 json_extract https://teradata.github.io/presto/docs/141t/functions/json.html 但如果我们不知道密钥,则没有提及提取 :( 我正在尝试找到有效的解决方案在 presto 和 hive 查询中,是否有适用于两者的通用查询?

您可以将 json 转换为 map(varchar, json) 并使用 unnest 处理它以展平:

-- sample data
WITH dataset (json_str) AS (
    VALUES (
            '{"Bkav":{"detected": false,"result": null},"Lionic":{"detected": true,"result": "Trojan.Generic.3611249"}}'
        )
) 

--query
select k "AV Engine Name", json_extract_scalar(v, '$.detected') "Detected Virus", json_extract_scalar(v, '$.result') "Result"
from (
        select cast(json_parse(json_str) as map(varchar, json)) as m
        from dataset
    )
cross join unnest (map_keys(m), map_values(m)) t(k, v)

输出:

AV Engine Name Detected Virus Result
Bkav false
Lionic true Trojan.Generic.3611249

@Guru 建议的 presto 查询有效,但对于 hive,没有简单的方法。

  1. 我不得不提取 json
  2. 用 replace 解析它以删除一些字符和括号
  3. 然后将其转换回地图,并重复一次以获取嵌套值
SELECT
    av_engine,
    str_to_map(regexp_replace(engine_result, '\}', ''),',', ':') AS output_map
FROM (
    SELECT
        str_to_map(regexp_replace(regexp_replace(get_json_object(raw_response, '$.scans'), '\"', ''), '\{',''),'\},', ':') AS key_val_map
    FROM restricted_antispam.abuse_malware_scanning
) AS S
LATERAL VIEW EXPLODE(key_val_map) temp AS av_engine, engine_result