如何使用 JSON_EXTRACT 或 JSON_EXTRACT_SCALAR 在 Big Query 中读取多级 JSON 数据

Posted

技术标签:

【中文标题】如何使用 JSON_EXTRACT 或 JSON_EXTRACT_SCALAR 在 Big Query 中读取多级 JSON 数据【英文标题】:how to read multiple levels of JSON data in Big Query using JSON_EXTRACT or JSON_EXTRACT_SCALAR 【发布时间】:2020-01-22 00:41:45 【问题描述】:

我正在尝试使用 Bigquery 中的 JSON_EXTRACT 读取 Bigquery 中的以下 JSON 结构。它说不支持的运算符路径“*”

在 BigQuery 中尽我所能尝试并请求您的帮助

错误: JSONPath 中不支持的运算符:*

****JSON 数据:** 只是具有多个值并且在阅读时出现问题的部分。需要阅读以下所有 4 个“id”值,例如并且还需要阅读所有其他列 在 Combo 部分下生成 4 行具有不同 ID、Type 等的。**

"Combos": [
  
    "Id": "1111",
    "Type": 0,
    "Description": "ABCD",
    "ComboDuration": 
      "StartDate": "2009-10-26T08:00:00",
      "EndDate": "2009-10-29T08:00:00"
    
  ,
  
    "Id": "2222",
    "Type": 1,
    "Description": "XYZ",
    "ComboDuration": 
      "StartDate": "2019-10-26T08:00:00",
      "EndDate": "2019-10-29T08:00:00"
    
  ,
  
    "Id": "39933",
    "Type": 3,
    "Description": "General",
    "ComboDuration": 
      "StartDate": "2019-10-26T08:00:00",
      "EndDate": "2019-10-29T08:00:00"
    
  ,
  
    "Id": "39934",
    "Type": 2,
    "Description": "ABCDXYZ",
    "ComboDuration": 
      "StartDate": "2019-10-26T08:00:00",
      "EndDate": "2019-10-29T08:00:00"
    
  ,

]

****Code:** P.S - conv_column is a string column where my JSON structure stored**

SELECT 
JSON_EXTRACT(conv_column,"$.Combos.*.Id") as combo_id
from lz.json_file

SELECT JSON_EXTRACT(conv_column,"$.Combos[*].Id") as combo_id
from lz.json_file

SELECT JSON_EXTRACT(conv_column,"$.Combos[?@.Id]") as combo_id
from lz.json_file

【问题讨论】:

@MikhailBerlyant - 征求您的意见 @Nanda - 注意:只有当他/她已经是给定帖子的一部分时,才会将此类“目标”消息发送给“收件人” - 否则 - 它只是被忽略 - 意味着没有按预期发送“目标” @MikhailBerlyant - 我不知道 cmets 在这里是如何工作的,非常感谢您的帮助和支持 【参考方案1】:

下面是标准 SQL 的 BigQuery 示例

#standardSQL
CREATE TEMP FUNCTION jsonparse(input STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
  return JSON.parse(input).map(x=>JSON.stringify(x));
"""; 
WITH `project.lz.json_file` AS (
  SELECT '''
  "Combos": [  
    "Id": "1111",
    "Type": 0,
    "Description": "ABCD",
    "ComboDuration": 
      "StartDate": "2009-10-26T08:00:00",
      "EndDate": "2009-10-29T08:00:00"
      ,  
    "Id": "2222",
    "Type": 1,
    "Description": "XYZ",
    "ComboDuration": 
      "StartDate": "2019-10-26T08:00:00",
      "EndDate": "2019-10-29T08:00:00"
      ,  
    "Id": "39933",
    "Type": 3,
    "Description": "General",
    "ComboDuration": 
      "StartDate": "2019-10-26T08:00:00",
      "EndDate": "2019-10-29T08:00:00"
      ,  
    "Id": "39934",
    "Type": 2,
    "Description": "ABCDXYZ",
    "ComboDuration": 
      "StartDate": "2019-10-26T08:00:00",
      "EndDate": "2019-10-29T08:00:00"
      ]  ''' AS conv_column
)
SELECT
  JSON_EXTRACT_SCALAR(combo, '$.Id') AS Id,
  JSON_EXTRACT_SCALAR(combo, '$.Type') AS Type,
  JSON_EXTRACT_SCALAR(combo, '$.Description') AS Description,
  JSON_EXTRACT_SCALAR(combo, '$.ComboDuration.StartDate') AS StartDate,
  JSON_EXTRACT_SCALAR(combo, '$.ComboDuration.EndDate') AS EndDate
FROM `project.lz.json_file`,
UNNEST(jsonparse(JSON_EXTRACT(conv_column, '$.Combos'))) combo

有输出

Row Id      Type    Description StartDate           EndDate  
1   1111    0       ABCD        2009-10-26T08:00:00 2009-10-29T08:00:00  
2   2222    1       XYZ         2019-10-26T08:00:00 2019-10-29T08:00:00  
3   39933   3       General     2019-10-26T08:00:00 2019-10-29T08:00:00  
4   39934   2       ABCDXYZ     2019-10-26T08:00:00 2019-10-29T08:00:00  

【讨论】:

非常感谢您的帮助。当我尝试用实际列“conv_column”替换 WITH 语句中的“Combos”时 - 变量是一个字符串并具有 JSON 结构,我在 jsonparse(STRING) 第 2 行得到“TypeError: Cannot read property 'map' of null ,第 26-27 列"。我正在使用的代码 sn-p 在下面, :CREATE TEMP FUNCTION jsonparse(input STRING) RETURNS ARRAY LANGUAGE js AS """ return JSON.parse(input).map(x=>JSON.stringify(x) ); """; WITH lz.json_file AS ( SELECT job_id,conv_column from lz.json_file ) 后跟您编码的语句 conv_column 已用作列名 - 由您的 json 字符串组成的列。玩提供的示例并将其调整为您实际拥有的任何内容:o) - 当然。我在下面尝试仍然得到相同的错误:CREATE TEMP FUNCTION jsonparse(input STRING) RETURNS ARRAY LANGUAGE js AS """ return JSON.parse(input).map(x=>JSON.stringify(x)); " ""; SELECT JSON_EXTRACT_SCALAR(combo, '$.Id') AS Id FROM lz.json_file, UNNEST(jsonparse(JSON_EXTRACT(conv_column, '$.Combos'))) 组合 您在我的回答中尝试过示例吗?您确定您在该列中的真实 json 文本与您的问题和我的回答中的一样吗?或者它(看起来)是其他/不同的东西,可以解释您的问题 非常感谢到目前为止的帮助。今天早上我花了一些时间来弄清楚输入数据发生了什么,问题在于不完整的 JSON 结构,我已经修复了相同的问题。它现在完全可以与我处理的所有测试用例一起工作,并且可以按预期提取数据。

以上是关于如何使用 JSON_EXTRACT 或 JSON_EXTRACT_SCALAR 在 Big Query 中读取多级 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章

当所述列的值为 NULL 时,我在可空列上使用 JSON_extract 函数的 where 语句得到确认?

JSON_EXTRACT 不适用于 BigQuery 中的布尔值

我想用 BigQuery 提取 Json 格式的数据。 UDF 或 json_extract

避免 BigQuery 中 JSON_EXTRACT 函数中的指数表示法

where子句中的mysql udf json_extract - 如何提高性能

where子句中的mysql udf json_extract - 如何提高性能