web-dev-qa-db-fra.com

Comment extraire des clés dans un objet tableau json imbriqué dans Presto?

J'utilise le dernier (0.117) Presto et j'essaye d'exécuter CROSS JOIN UNNEST avec un tableau JSON complexe comme celui-ci.

[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}, ...]

Pour ce faire, j'ai d'abord essayé de créer un tableau avec les valeurs id par

SELECT CAST(JSON_EXTRACT('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]', '$..id') AS ARRAY<BIGINT>)

mais ça ne marche pas.

Quel est le meilleur chemin JSON pour extraire les valeurs de id?

14
k-kawa

Vous pouvez convertir le JSON en un TABLEAU de MAP et utiliser la fonction transform lambda pour extraire la clé "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)

production:

 [1, 2]
7
Wenlei Xie

Cela résoudra votre problème. Il est plus générique converti en un tableau de json (moins sujet aux erreurs étant donné une structure de carte arbitraire):

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)

Sortie en presto:

 [1,2]

... Je suis tombé sur une situation où une liste de jsons était imbriquée dans un json. Ma liste de jsons avait une structure de carte imbriquée ambiguë. Le code suivant renvoie un tableau de valeurs en fonction d'une clé spécifique dans une liste de jsons.

  1. Extraire la liste à l'aide de JSON EXTRACT
  2. Cast la liste comme un tableau de jsons
  3. Parcourez les éléments json du tableau à l'aide de la fonction TRANSFORM et extrayez la valeur de la clé qui vous intéresse.

>

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

Maintenant, vous pouvez utiliser presto-troisième-fonctions , il fournit json_array_extract, vous pouvez extraire les informations du tableau json comme ceci:

    select 
           json_array_extract_scalar(arr1, '$.book.id') 
    from 
           (values ('[{"book":{"id":"12"}}, {"book":{"id":"14"}}]')) t(arr1)

la sortie est:

    [12, 14]
4
aaronshan

J'ai finalement renoncé à trouver un chemin JSON simple pour les extraire.

Au lieu de cela, j'ai écrit une requête sale redondante comme la suivante pour faire la tâche.

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
  ...

Je veux toujours connaître la meilleure pratique si vous connaissez un autre bon moyen de CROSS JOIN eux!

2
k-kawa