web-dev-qa-db-ja.com

Prestoでネストされたjson配列オブジェクトのキーを抽出する方法は?

私は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パスは何ですか?

14
k-kawa

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]
7
Wenlei Xie

これはあなたの問題を解決します。これは、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のリスト内の特定のキーを指定して値の配列を返します。

  1. JSON EXTRACTを使用してリストを抽出する
  2. リストをjsonの配列としてキャストする
  3. TRANSFORM関数を使用して配列内のjson要素をループし、目的のキーの値を抽出します。

>

TRANSFORM(CAST(JSON_EXTRACT(json, '$.path.toListOfJSONs') AS ARRAY<JSON>),
          x -> JSON_EXTRACT_SCALAR(x, '$.id')) as id
6
Attila Dobi

これで、 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]
4
aaronshan

最後に、それらを抽出するための単純な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に別の良い方法を知っているなら、私はまだベストプラクティスを知りたいです!

2
k-kawa