web-dev-qa-db-fra.com

Bigquery - json_extract tous les éléments d'un tableau

j'essaie d'extraire deux clés de chaque json dans un tableau de jsons (en utilisant l'héritage sql) actuellement j'utilise la fonction d'extrait de json:

json_extract(json_column , '$[1].X') AS X,
json_extract(json_column , '$[1].Y') AS Y,

comment puis-je le faire fonctionner sur chaque json dans la 'colonne json arry', et pas seulement [1] (par exemple)?

Un exemple json:

[

{"blabla":000,"X":1,"blabla":000,"blabla":000,"blabla":000,,"Y":"2"},

{"blabla":000,"X":3,"blabla":000,"blabla":000,"blabla":000,,"Y":"4"},

]   

merci d'avance!

5
am_am

Commençons par un problème similaire - ce n'est pas un moyen très pratique d'extraire tous les e-mails d'un tableau json:

SELECT id
  , [ JSON_EXTRACT_SCALAR(JSON_EXTRACT(payload, '$.commits'), '$[0].author.email')  
      , JSON_EXTRACT_SCALAR(JSON_EXTRACT(payload, '$.commits'), '$[1].author.email')  
      , JSON_EXTRACT_SCALAR(JSON_EXTRACT(payload, '$.commits'), '$[2].author.email')  
      , JSON_EXTRACT_SCALAR(JSON_EXTRACT(payload, '$.commits'), '$[3].author.email')
    ] emails
FROM `githubarchive.day.20180830` 
WHERE type='PushEvent' 
AND id='8188163772'

enter image description here

La meilleure façon dont nous disposons en ce moment est d'utiliser du JavaScript dans un UDF pour diviser un tableau json en un tableau SQL:

CREATE TEMP FUNCTION json2array(json STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
  return JSON.parse(json).map(x=>JSON.stringify(x));
"""; 

SELECT * EXCEPT(array_commits),
  ARRAY(SELECT JSON_EXTRACT_SCALAR(x, '$.author.email') FROM UNNEST(array_commits) x) emails
FROM (
  SELECT id
    , json2array(JSON_EXTRACT(payload, '$.commits')) array_commits
  FROM `githubarchive.day.20180830` 
  WHERE type='PushEvent' 
  AND id='8188163772'
)

enter image description here

15
Felipe Hoffa

L'exemple ci-dessous pour BigQuery Standard SQL et vous permet d'être proche de la façon standard de travailler avec JSONPath et aucune manipulation supplémentaire n'est nécessaire, il vous suffit donc d'utiliser la fonction CUSTOM_JSON_EXTRACT(json, json_path)

#standardSQL
CREATE TEMPORARY FUNCTION CUSTOM_JSON_EXTRACT(json STRING, json_path STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
        return jsonPath(JSON.parse(json), json_path);
"""
OPTIONS (
    library="gs://your_bucket/jsonpath-0.8.0.js"
);
WITH t AS (
SELECT '''
[
{"blabla1":1,"X":1,"blabla2":3,"blabla3":5,"blabla4":7,"Y":"2"},
{"blabla1":2,"X":3,"blabla2":4,"blabla3":6,"blabla4":8,"Y":"4"}
]   
''' AS json_column 
)
SELECT 
  CUSTOM_JSON_EXTRACT(json_column , '$[*].X') AS X,
  CUSTOM_JSON_EXTRACT(json_column , '$[*].Y') AS Y
FROM t   

le résultat sera

Row X   Y    
1   1   2    
    3   4      

Remarque: pour surmonter la "limitation" actuelle de BigQuery pour JsonPath, la solution ci-dessus utilise fonction personnalisée avec bibliothèque externe - jsonpath-0.8.0.js qui peut être téléchargé depuis https://code.google.com/archive/p/jsonpath/downloads et téléchargé vers Google Cloud Storage - gs: //your_bucket/jsonpath-0.8.0. js

Relisez simplement la réponse de Felipe - pour son exemple, la solution ci-dessus ressemblera à celle ci-dessous (tout comme FYI)

SELECT 
  id, 
  CUSTOM_JSON_EXTRACT(payload, '$.commits[*].author.email') emails
FROM `githubarchive.day.20180830` 
WHERE type='PushEvent' 
AND id='8188163772'
6
Mikhail Berlyant