私はlatest(0.117)Prestoを使用して、このような複雑なJSON配列でCROSS JOIN UNNESTを実行しようとしています。
[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}, ...]
これを行うには、まず[〜#〜] array [〜#〜]をidの値で作成しようとしました
SELECT CAST(JSON_EXTRACT('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]', '$..id') AS ARRAY<BIGINT>)
しかし、それは機能しません。
idの値を抽出するのに最適なJSONパスは何ですか?
JSONをMAPのARRAYにキャストし、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)
Prestoでの出力:
[1,2]
... jsonのリストがjson内にネストされている状況に遭遇しました。 jsonの私のリストには、あいまいなネストされたマップ構造がありました。次のコードは、jsonのリスト内の特定のキーを指定して値の配列を返します。
>
TRANSFORM(CAST(JSON_EXTRACT(json, '$.path.toListOfJSONs') AS ARRAY<JSON>),
x -> JSON_EXTRACT_SCALAR(x, '$.id')) as id
これで、 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パスの検索をあきらめました。
代わりに、次のような冗長なダーティクエリを記述して、タスクを完了させました。
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に別の良い方法を知っているなら、私はまだベストプラクティスを知りたいです!