如何在 Presto 中提取嵌套 json 数组对象中的键?
How to extract keys in a nested json array object in Presto?
我正在使用最新的 (0.117) Presto 并尝试使用这样的复杂 JSON 数组执行 CROSS JOIN UNNEST。
[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}, ...]
为此,我首先尝试通过
使用 id 的值创建一个 ARRAY
SELECT CAST(JSON_EXTRACT('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]', '$..id') AS ARRAY<BIGINT>)
但是没用。
提取 id 值的最佳 JSON 路径是什么?
我终于放弃了寻找一个简单的 JSON 提取它们的路径。
相反,我编写了如下冗余脏查询来完成任务。
SELECT
...
FROM
(
SELECT
SLICE(ARRAY[
JSON_EXTRACT(json_column, '$[0].id'),
JSON_EXTRACT(json_column, '$[1].id'),
JSON_EXTRACT(json_column, '$[2].id'),
...
], JSON_ARRAY_LENGTH(json_column)) ids
FROM
the.table
) t1
CROSS JOIN UNNEST(ids) AS t2(id)
WHERE
...
如果您知道另一种 CROSS JOIN 它们的好方法,我仍然想知道最佳实践!
现在,你可以使用 presto-third-functions ,它提供了 json_array_extract
功能,你可以像这样提取 json 数组信息:
select
json_array_extract_scalar(arr1, '$.book.id')
from
(values ('[{"book":{"id":"12"}}, {"book":{"id":"14"}}]')) t(arr1)
输出为:
[12, 14]
您可以将 JSON 转换为 MAP 的数组,并使用 transform
lambda 函数提取 "id" 键:
select
TRANSFORM(CAST(JSON_PARSE(arr1) AS ARRAY<MAP<VARCHAR, VARCHAR>>), entry->entry['id'])
from
(values ('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]')) t(arr1)
输出:
[1, 2]
这将解决您的问题。它更通用地转换为 json 的 ARRAY(给定任意映射结构更不容易出错):
select
TRANSFORM(CAST(JSON_PARSE(arr1) AS ARRAY<JSON>),
x -> JSON_EXTRACT_SCALAR(x, '$.id'))
from
(values ('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]')) t(arr1)
快速输出:
[1,2]
... 我 运行 遇到 json 的列表嵌套在 json 中的情况。我的 json 列表有一个不明确的嵌套映射结构。以下代码 returns 给定 json 列表中特定键的值数组。
- 使用 JSON EXTRACT
提取列表
- 将列表转换为 jsons
的数组
- 使用 TRANSFORM 函数遍历数组中的 json 个元素,并提取您感兴趣的键的值。
>
TRANSFORM(CAST(JSON_EXTRACT(json, '$.path.toListOfJSONs') AS ARRAY<JSON>),
x -> JSON_EXTRACT_SCALAR(x, '$.id')) as id
我正在使用最新的 (0.117) Presto 并尝试使用这样的复杂 JSON 数组执行 CROSS JOIN UNNEST。
[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}, ...]
为此,我首先尝试通过
使用 id 的值创建一个 ARRAYSELECT CAST(JSON_EXTRACT('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]', '$..id') AS ARRAY<BIGINT>)
但是没用。
提取 id 值的最佳 JSON 路径是什么?
我终于放弃了寻找一个简单的 JSON 提取它们的路径。
相反,我编写了如下冗余脏查询来完成任务。
SELECT
...
FROM
(
SELECT
SLICE(ARRAY[
JSON_EXTRACT(json_column, '$[0].id'),
JSON_EXTRACT(json_column, '$[1].id'),
JSON_EXTRACT(json_column, '$[2].id'),
...
], JSON_ARRAY_LENGTH(json_column)) ids
FROM
the.table
) t1
CROSS JOIN UNNEST(ids) AS t2(id)
WHERE
...
如果您知道另一种 CROSS JOIN 它们的好方法,我仍然想知道最佳实践!
现在,你可以使用 presto-third-functions ,它提供了 json_array_extract
功能,你可以像这样提取 json 数组信息:
select
json_array_extract_scalar(arr1, '$.book.id')
from
(values ('[{"book":{"id":"12"}}, {"book":{"id":"14"}}]')) t(arr1)
输出为:
[12, 14]
您可以将 JSON 转换为 MAP 的数组,并使用 transform
lambda 函数提取 "id" 键:
select
TRANSFORM(CAST(JSON_PARSE(arr1) AS ARRAY<MAP<VARCHAR, VARCHAR>>), entry->entry['id'])
from
(values ('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]')) t(arr1)
输出:
[1, 2]
这将解决您的问题。它更通用地转换为 json 的 ARRAY(给定任意映射结构更不容易出错):
select
TRANSFORM(CAST(JSON_PARSE(arr1) AS ARRAY<JSON>),
x -> JSON_EXTRACT_SCALAR(x, '$.id'))
from
(values ('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]')) t(arr1)
快速输出:
[1,2]
... 我 运行 遇到 json 的列表嵌套在 json 中的情况。我的 json 列表有一个不明确的嵌套映射结构。以下代码 returns 给定 json 列表中特定键的值数组。
- 使用 JSON EXTRACT 提取列表
- 将列表转换为 jsons 的数组
- 使用 TRANSFORM 函数遍历数组中的 json 个元素,并提取您感兴趣的键的值。
>
TRANSFORM(CAST(JSON_EXTRACT(json, '$.path.toListOfJSONs') AS ARRAY<JSON>),
x -> JSON_EXTRACT_SCALAR(x, '$.id')) as id