Bigquery - json_extract всех элементов из массива - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь извлечь два ключа из каждого json в массиве jsons (используя sql legacy) В настоящее время я использую функцию извлечения JSON:

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

как мне заставить его работать на каждом json в 'столбце json arry', а не только на [1] (например)?

Пример 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"},

]   

спасибо заранее!

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Ниже приведен пример для BigQuery Standard SQL, который позволяет вам приблизиться к стандартному способу работы с JSONPath и не требует дополнительных манипуляций, поэтому вы просто используете 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   

результат будет

Row X   Y    
1   1   2    
    3   4      

Примечание: чтобы преодолеть текущее «ограничение» BigQuery для JsonPath, вышеприведенное решение использует пользовательскую функцию вместе с внешней библиотекой - jsonpath-0.8.0.js, которую можно загрузить с https://code.google.com/archive/p/jsonpath/downloads и загружено в Google Cloud Storage - gs: //your_bucket/jsonpath-0.8.0.js

Просто перечитайте ответ Фелипе - для его примера выше решение будет выглядеть ниже (так же, как и к вашему сведению)

SELECT 
  id, 
  CUSTOM_JSON_EXTRACT(payload, '$.commits[*].author.email') emails
FROM `githubarchive.day.20180830` 
WHERE type='PushEvent' 
AND id='8188163772'
0 голосов
/ 01 сентября 2018

Давайте начнем с аналогичной проблемы - это не очень удобный способ извлечь все электронные письма из массива 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

Лучший способ справиться с этим сейчас - использовать JavaScript в UDF для разделения массива json на массив 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

...