在 BigQuery 中嵌套多个重复字段

Posted

技术标签:

【中文标题】在 BigQuery 中嵌套多个重复字段【英文标题】:Nest multiple repeated fields in BigQuery 【发布时间】:2016-03-03 19:28:52 【问题描述】:

通过导入JSON文件加载GBQ中的重复字段

通过在 BigQuery 中导入包含重复记录的 JSON 文件,您可以创建包含嵌套重复字段的表。

例如,对于架构:

[
"type":"STRING", "name":"item",
"type":"RECORD", "name":"click", "mode":"REPEATED", "fields": ["type":"TIMESTAMP", "name":"click_time", "type":"STRING", "name":"userid"]

]

您可以加载一个项目点击的 JSON 文件,并为每个项目重复点击。该表将包含字段itemclick.click_timeclick.userid

我的问题

假设您有一个 CSV 文件,该文件已将上述 JSON 项目点击展平,每次点击一行,但 clickitem 的值重复。您能否将其加载到 GBQ 中并使用 GBQ 查询将其转换为您在加载带有重复字段的 JSON 文件时所拥有的等效表?

对导入的 CSV 表执行 GBQ 查询后生成的表应包含 click.click_timeclick.userid 项作为字段。

【问题讨论】:

您能否提供您要加载的文件的样本? Mikhail 打败了我 - 请参阅下面的示例文件和一个很好的答案。我能够实现 Mikhail 的解决方案,以及涉及多个 GROUP BY 字段的模式,如 item、item_category1、item_category2,具有关联的 clicks.click_time、clicks.userid。 Mikhail 说明的 UDF 解决方法比尝试使用 NEST 更灵活,尽管正如他在另一篇文章中提到的那样,它可能会导致更高的计费水平。 【参考方案1】:

随着 BigQuery 标准 SQL 的引入,我们有了处理记录的简单方法 试试下面,不要忘记取消选中 Show Options 下的 Use Legacy SQL 复选框

WITH YourTable AS (
  SELECT 'a1' AS item,  '2016-03-03 19:52:23 UTC' AS click_time, 'u1' AS userid UNION ALL
  SELECT 'a1' AS item,  '2016-03-03 19:52:23 UTC' AS click_time, 'u2' AS userid UNION ALL
  SELECT 'a1' AS item,  '2016-03-03 19:52:23 UTC' AS click_time, 'u3' AS userid UNION ALL
  SELECT 'a1' AS item,  '2016-03-03 19:52:23 UTC' AS click_time, 'u4' AS userid UNION ALL
  SELECT 'a2' AS item,  '2016-03-03 19:52:23 UTC' AS click_time, 'u1' AS userid UNION ALL
  SELECT 'a2' AS item,  '2016-03-03 19:52:23 UTC' AS click_time, 'u2' AS userid
)
SELECT item, ARRAY_AGG(STRUCT(click_time, userid)) AS clicks
FROM YourTable
GROUP BY item

【讨论】:

不错的更新。您知道 BigQuery 标准 SQL 语法和功能文档的链接吗?【参考方案2】:

假设您已将表中的数据展平:

item    click_time  userid   
a1  2016-03-03 19:52:23 UTC u1   
a1  2016-03-03 19:52:23 UTC u2   
a1  2016-03-03 19:52:23 UTC u3   
a1  2016-03-03 19:52:23 UTC u4   
a2  2016-03-03 19:52:23 UTC u1   
a2  2016-03-03 19:52:23 UTC u2

在 GBQ Query 下执行您所要求的操作: 请注意:您需要使用“Allow Large Result”和“UnFlatten”选项写入表格

SELECT *
FROM JS( 
  ( // input table 
    SELECT item, NEST(CONCAT(STRING(click_time), ',', STRING(userid))) AS clicks 
    FROM YourTable
    GROUP BY item
  ), 
  item, clicks, // input columns 
  "[ // output schema 
    'name': 'item', 'type': 'STRING',
     'name': 'clicks', 'type': 'RECORD',
     'mode': 'REPEATED',
     'fields': [
       'name': 'click_time', 'type': 'STRING',
       'name': 'userid', 'type': 'STRING'
       ]    
     
  ]", 
  "function(row, emit)  // function 
    var c = []; 
    for (var i = 0; i < row.clicks.length; i++)  
      x = row.clicks[i].split(','); 
      t = click_time:x[0], 
            userid:x[1] ;
      c.push(t); 
    ; 
    emit(item: row.item, clicks: c); 
  "
) 

预期结果如下

【讨论】:

以上是关于在 BigQuery 中嵌套多个重复字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在存储为字符串的 bigquery 字段中取消嵌套多个数组?

如何在bigquery中获取重复嵌套字段的长度

在 Power BI 中使用 BigQuery 重复/嵌套字段

Google BigQuery - 更新嵌套的重复字段

如何在 BigQuery 中取消嵌套多个数组?

在 BigQuery 中展平嵌套和重复的结构(标准 SQL)