簡體   English   中英

更新嵌套的 bigquery json 元素

[英]Update nested bigquery json element

我有一個像這樣的大查詢模式:

visitorId                    INTEGER NULLABLE
visitID                      INTEGER NULLABLE
hits                         RECORD  REPEATED
hits.eventInfo               RECORD  NULLABLE   
hits.eventInfo.eventCategory STRING  NULLABLE   
hits.eventInfo.eventLabel    STRING  NULLABLE   

樣本數據為:

visitorId  visitId  hits.eventInfo.eventCategory hits.eventInfo.eventCategory
123456     1        abc                          {"info":"secret", "otherfields":"blah"}
                    lmn                          {"info":"secret", "otherfields":"blah"}
                    xyz                          {"info":"secret", "otherfields":"blah"}
124557     1        abc                          {"info":"secret", "otherfields":"blah"}
                    lmn                          {"info":"secret", "otherfields":"blah"}
                    xyz                          {"info":"secret", "otherfields":"blah"}

只有當 eventCategory 是"abc",我才需要刪除 "info":"secret "。

我是一個大查詢新手。 經過多次打擊和嘗試,我能夠做到這一點,但不幸的是現在卡住了。

UPDATE `project.dataset.ga_sessions_20200608`
SET hits = ARRAY(
  SELECT AS STRUCT * REPLACE((REGEXP_REPLACE(eventInfo.eventLabel, r"\"info\":\"[a-z A-Z]*\",", "")) AS eventInfo.eventLabel) from UNNEST(hits) 
)
WHERE (select eventInfo.eventLabel from UNNEST(hits)) LIKE '%info%'

這里有兩個問題。

  • 設置部分不起作用:(
  • 其中 (subselect) 中的子查詢未提供標量 output:'(

任何幫助,指針將不勝感激。

使用 DML 方法 ( UPDATE ) 與在整個表上運行的批處理過程相比具有挑戰性,原因有幾個(其中一些您已經給出):

  • 需要更新的記錄中的子字段是 JSON 字符串化的
  • 更新的本質是通過字符串表示中的字段鍵進行過濾
  • 記錄本身是表頂層的重復類型,並包含結構

這使您處於 position 的境地,必須重建hitseventInfo的整個結構以替換它的一個字段(它本身是一個 JSON 編碼結構,盡管 BigQuery 對此視而不見並將其視為字符串)。

AFAIK BigQuery 沒有 function 從 json 編組真正的 STRUCT,因此正則表達式可能是實際消除 json 編碼列中不需要的字段的唯一方法。

這里的WHERE條件可以利用JSON_EXTRACT_SCALAR標准SQL function來捕捉json中實際存在的條件。

因此,一種可能的純 BigQuery 方法(無 UDF)可能如下所示:

#standardSQL
UPDATE
  `project.dataset.table_DATE`
SET
  --reconstruct hits column as an array
  hits = ARRAY(
  SELECT
       --reconstruct each struct of hits
    AS STRUCT * REPLACE( (
      SELECT
        --reconstruct eventInfo...
        AS STRUCT eventInfo.* REPLACE(
          --with eventLabel replaced with a filtered version
          REGEXP_REPLACE(eventInfo.eventLabel, r"\"secret\":\"[A-Za-z\p{L}]* [A-Za-z\p{L}]*\",", "") AS eventLabel)
        ) AS eventInfo )
  FROM
    UNNEST(hits) AS hits )
WHERE
  --Only for rows where at least one eventLabel's json contains a `secret` key
  EXISTS (SELECT JSON_EXTRACT_SCALAR(h.eventInfo.eventLabel, "$.secret") is not null from unnest(hits) as h)

請注意,那里的正則表達式可能需要根據數據格式進行一些更改。 在這里,我假設一個可能包含 unicode 個字符(如名字 + 姓氏)的兩個單詞的秘密值。

正則表達式部分可能由UDF提供更好的服務,盡管對於大表來說它們可能很慢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM