BigQuery UPDATE 嵌套数组字段
Posted
技术标签:
【中文标题】BigQuery UPDATE 嵌套数组字段【英文标题】:BigQuery UPDATE nested array field 【发布时间】:2018-05-04 14:02:26 【问题描述】:我需要使用另一个表中的值更新一个表中的嵌套字段。 使用this solution 我想出了一些可行的方法,但并不完全符合我的要求。 这是我的解决方案:
#standardSQL
UPDATE
`attribution.daily_sessions_20180301_copy1` AS target
SET
hits = ARRAY(
SELECT AS STRUCT * REPLACE(ARRAY(
SELECT AS STRUCT *
FROM(
SELECT AS STRUCT * REPLACE(map.category AS productCategoryAttribute) FROM UNNEST(product))) AS product) FROM UNNEST(hits)
)
FROM
`attribution.attribute_category_map`
AS map
WHERE
(
SELECT REPLACE(LOWER(prod.productCategory), 'amp;', '') FROM UNNEST(target.hits) AS h,
UNNEST(h.product) AS prod LIMIT 1) = map.raw_name
attribute_category_map 是一个有两列的表,我在其中查找第 1 列中的对应值,并用第 2 列中的值替换目标表中的数据。我取得的最佳结果 - 用相同的值更新了一行上的所有嵌套字段,这是仅对第一个嵌套字段更正,而不是使用特定值更新每个嵌套字段。
主表的简化架构:
[
"name":"sessionId",
"type":"STRING",
"mode":"NULLABLE"
,
"name":"hits",
"type":"RECORD",
"mode":"REPEATED",
"fields":[
"name":"product",
"type":"RECORD",
"mode":"REPEATED",
"fields":[
"name":"productCategory",
"type":"STRING",
"mode":"NULLABLE"
,
"name":"productCategoryAttribute",
"type":"STRING",
"mode":"NULLABLE"
]
]
]
会话行中通常有多个匹配,一个匹配中有多个产品。值看起来像那些(如果你取消嵌套):
-----------------------------------------------------------------------------
sessionId | hits.product.productCategory| hit.product.productCategoryAttribute
-----------------------------------------------------------------------------
1 | automotive chemicals | null
1 | automotive tools | null
1 | null | null
2 | null | null
2 | automotive chemicals | null
2 | null | null
3 | null | null
3 | bed accessories | null
4 | null | null
4 | null | null
4 | automotive chemicals | null
4 | null | null
-----------------------------------------------------------------------------
映射表的架构:
[
"name":"raw_name",
"type":"STRING",
"mode":"NULLABLE"
,
"name":"category",
"type":"STRING",
"mode":"NULLABLE"
]
具有这样的值:
---------------------------------------------------
raw_name |category |
---------------------------------------------------
automotive chemicals |d1y2 - automotive chemicals|
automotive paint |dijf1 - automotive paint |
automotive tools |efw1 - automotive tools |
baby & infant toys |wwfw - baby & infant toys |
batteries & power |fdsv- batteries & power |
bed accessories |0k77 - bed accessories |
bike racks |12df - bike racks |
--------------------------------------------------
我想要的结果:
-----------------------------------------------------------------------------
sessionId | hits.product.productCategory| hit.product.productCategoryAttribute
-----------------------------------------------------------------------------
1 | automotive chemicals | d1y2 - automotive chemicals
1 | automotive tools | efw1 - automotive tools
1 | null | null
2 | null | null
2 | automotive chemicals | d1y2 - automotive chemicals
2 | null | null
3 | null | null
3 | bed accessories | 0k77 - bed accessories
4 | null | null
4 | null | null
4 | automotive chemicals | d1y2 - automotive chemicals
4 | null | null
-----------------------------------------------------------------------------
我需要从主表中取值 productCategory,在 map 表中的 raw_name 列中查找,从列类别中取值并将其放入主表的 productCategoryAttribute 列。主要问题是目标字段是双重嵌套的,我不知道如何直接加入它们。
【问题讨论】:
您的查找所基于的主表中的列是什么?您还应该在主表上提供一些详细信息,并提供输入数据和预期数据的简化模式和示例。所以我们实际上可以帮助你:o) 您对数组中的每个元素使用相同的 map.category,因此预计数组中的所有元素都是相同的。正如 Mikhail 已经说过的,查看一些示例数据、您获得的结果以及您想要获得的结果会非常有帮助。 @MikhailBerlyant,我添加了一些细节,现在更清楚了吗? @Daria,我得到了这个“数组中每个元素的相同 map.category”部分,我意识到这是问题所在,我只是无法更接近正确的查询。我在上面添加了一些细节。 【参考方案1】:以下已测试! 保持整个表的架构/数据不变,仅根据各自的映射更新 productCategoryAttribute 的值
#standardSQL
UPDATE `project.dataset.your_table` t
SET hits =
ARRAY(
SELECT AS STRUCT * REPLACE(
ARRAY(
SELECT AS STRUCT product.* REPLACE(
CASE WHEN map.raw_name = product.productCategory THEN category
ELSE productCategoryAttribute END AS productCategoryAttribute)
FROM UNNEST(product) product
LEFT JOIN UNNEST(agg_map.map) map
ON map.raw_name = product.productCategory
) AS product)
FROM UNNEST(hits) hit
)
FROM (SELECT ARRAY_AGG(row) map FROM `project.dataset.map` row) agg_map
WHERE TRUE
注意:上述解决方案假设映射表没有那么大,因为它依赖于将整个映射表聚合到一个数组中
【讨论】:
谢谢!它按预期工作。但是对于更大的目标表发生错误 - 错误:查询执行期间超出资源:无法在分配的内存中执行查询。用于 UPDATE 的排序运算符使用了太多内存。映射表只有约 400 对,所以我认为这不是问题。也许我可以限制最终 WHERE 子句中处理的数据量?以上是关于BigQuery UPDATE 嵌套数组字段的主要内容,如果未能解决你的问题,请参考以下文章
如何在存储为字符串的 bigquery 字段中取消嵌套多个数组?