【问题标题】:Bigquery - json_extract all elements from an arrayBigquery - json_extract 数组中的所有元素
【发布时间】:2019-02-06 18:22:16
【问题描述】:

我正在尝试从一组 json 中的每个 json 中提取两个密钥(使用 sql legacy) 目前我正在使用 json 提取功能:

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

我怎样才能让它在'json arry column'的每个json上运行,而不仅仅是[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"},

]   

提前致谢!

【问题讨论】:

标签: sql arrays json google-bigquery legacy-sql


【解决方案1】:

2020 年更新:JSON_EXTRACT_ARRAY()

现在 BigQuery 支持JSON_EXTRACT_ARRAY()

例如,要解决这个特定的问题:

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


上一个答案

让我们从一个类似的问题开始——这不是从 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'

我们现在处理这个问题的最好方法是在 UDF 中使用一些 JavaScript 将 json-array 拆分为 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'
)

【讨论】:

  • 这个问题有没有更好的更新答案?
【解决方案2】:

2020 年 5 月 1 日更新

一个新函数 JSON_EXTRACT_ARRAY 刚刚添加到 JSON 列表中 职能。此函数允许您将 JSON 文档的内容提取为 一个字符串数组。

所以在下面你可以用内置函数 JSON_EXTRACT_ARRAY 替换 CUSTOM_JSON_EXTRACT UDF 的使用,如下例所示

#standardSQL
SELECT 
  JSON_EXTRACT_SCALAR(json , '$.X') AS X,
  JSON_EXTRACT_SCALAR(json , '$.Y') AS Y
FROM t, UNNEST(JSON_EXTRACT_ARRAY(json_column , '$')) json   

==============

下面的 BigQuery 标准 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 的“限制”,上述解决方案使用 custom function 以及 external library - jsonpath-0.8.0.js,可以从 https://code.google.com/archive/p/jsonpath/downloads 下载并上传到 Google Cloud Storage - gs://your_bucket /jsonpath-0.8.0.js

只需重新阅读 Felipe 的答案 - 他的上述示例解决方案将如下所示(仅供参考)

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 2021-09-21
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多