我无法加入重复的嵌套字段,同时仍保留BigQuery中的原始行结构。
对于我的示例,我会将两个表称为A
和B
。
表A中的记录如下所示:
{
"url":"some url",
"repeated_nested": [
{"key":"some key","property":"some property"}
]
}
表B中的记录如下所示:
{
"key":"some key",
"property2": "another property"
}
我希望找到一种方法将这些数据连接在一起,以生成如下所示的行:
{
"url":"some url",
"repeated_nested": [
{
"key":"some key",
"property":"some property",
"property2":"another property"
}
]
}
我尝试的第一个查询是:
SELECT
url, repeated_nested.key, repeated_nested.property, repeated_nested.property2
FROM A
AS lefttable
LEFT OUTER JOIN B
AS righttable
ON lefttable.key=righttable.key
这不起作用,因为BQ无法连接重复的嵌套字段。每行没有唯一标识符。如果我在FLATTEN
上进行repeated_nested
,那么我不确定如何正确地将原始行重新组合在一起。
数据使得url
始终与其具有相同的repeated_nested
字段。因此,我能够使用UDF进行解决方法,将这个重复的嵌套对象整理成JSON字符串,然后再次展开它:
SELECT url, repeated_nested.key, repeated_nested.property, repeated_nested.property2
FROM
JS(
(
SELECT basetable.url as url, repeated_nested
FROM A as basetable
LEFT JOIN (
SELECT url, CONCAT("[", GROUP_CONCAT_UNQUOTED(repeated_nested_json, ","), "]") as repeated_nested
FROM
(
SELECT
url,
CONCAT(
'{"key": "', repeated_nested.key, '",',
' "property": "', repeated_nested.property, '",',
' "property2": "', mapping_table.property2, '"',
'}'
)
) as repeated_nested_json
FROM (
SELECT
url, repeated_nested.key, repeated_nested.property
FROM A
GROUP BY url, repeated_nested.key, repeated_nested.property
) as urltable
LEFT OUTER JOIN [SDF.alchemy_to_ric]
AS mapping_table
ON urltable.repeated_nested.key=mapping_table.key
)
GROUP BY url
) as companytable
ON basetable.url = urltable.url
),
// input columns:
url, repeated_nested_json,
// output schema:
"[{'name': 'url', 'type': 'string'},
{'name': 'repeated_nested_json', 'type': 'RECORD', 'mode':'REPEATED', 'fields':
[ { 'name': 'key', 'type':'string' },
{ 'name': 'property', 'type':'string' },
{ 'name': 'property2', 'type':'string' }]
}]",
// UDF:
"function(row, emit) {
parsed_repeated_nested = [];
try {
if ( row.repeated_nested_json != null ) {
parsed_repeated_nested = JSON.parse(row.repeated_nested_json);
}
} catch (ex) { }
emit({
url: row.url,
repeated_nested: parsed_repeated_nested
});
}"
)
此解决方案适用于小型表。但是我正在使用的真实生活表中的列数比上面的例子多了很多。当除url
和repeated_nested_json
之外还有其他字段时,它们都必须通过UDF传递。当我使用大约50 gb范围的表时,一切都很好。但是,当我将UDF和查询应用于500-1000 GB的表时,我从BQ收到内部服务器错误。
最后,我只需要GCS中新行分隔的JSON格式的所有数据。作为最后的努力,我尝试将所有字段连接成一个JSON字符串(这样我只有一列)希望我可以将其导出为CSV并拥有我需要的东西。但是,导出过程转义了双引号并在JSON字符串周围添加了双引号。根据BQ关于工作的文档(https://cloud.google.com/bigquery/docs/reference/v2/jobs),有一个属性configuration.query.tableDefinitions.(key).csvOptions.quote
可以帮助我。但我无法弄清楚如何让它发挥作用。
是否有人就他们如何应对这种情况提出建议?
答案 0 :(得分:1)
我从来没有这样做,但您应该能够使用flatten
,然后加入,然后使用nest
重新获得重复字段。
文档声明BigQuery总是会使查询结果变得扁平化,但这似乎是错误的:如果设置目标表,则可以选择不使结果变平。然后,您应该能够将该表作为JSON导出到存储。
另请参阅this answer了解如何让nest
工作。
答案 1 :(得分:0)
@AndrewBackes - 本周我们针对UDF内存相关问题推出了一些修复程序;这里有一些关于根本原因的详细信息https://stackoverflow.com/a/36275462/5265394和https://stackoverflow.com/a/35563562/5265394。
您的查询的UDF版本现在正在为我工作;你可以验证一下吗?