取消嵌套 BigQuery 和 BigTable 中的大量列

Unnesting a big quantity of columns in BigQuery and BigTable

我在 BigTable 中有一个 table,只有一个列族,包含一些主要数据。我正在按照 Google 云指南从 BigTable (https://cloud.google.com/bigquery/external-data-bigtable) 查询 BigTable 数据,到目前为止一切顺利。

我已经创建了 table 定义文件,就像所需的文档一样:

{
    "sourceFormat": "BIGTABLE",
    "sourceUris": [
        "https://googleapis.com/bigtable/projects/{project_id}/instances/{instance_id}/tables/{table_id}"
    ],
    "bigtableOptions": {
        "readRowkeyAsString": "true",
        "columnFamilies": [
            {
                "familyId": "leads",
                "columns": [
                    {
                        "qualifierString": "Id",
                        "type": "STRING"
                    },
                    {
                        "qualifierString": "IsDeleted",
                        "type": "STRING"
                    },
                    ...
                ]
            }
        ]
    }
}

但随后,事情开始向南发展......

这是 BigQuery“table”最终的样子:

每一行都是一个行键,每一列内都有一个嵌套单元格,我需要的唯一值是 leads.Id.cell 中的 value(在本例中)

经过一番搜索,我找到了解决方法:

所以在我的情况下它会是这样的:

SELECT    
    ARRAY_TO_STRING(ARRAY(SELECT value FROM UNNEST(leads.Id.cell)), "") AS Id,
    ...
FROM xxx

问题是我正在处理一个每行超过 600 列的数据集。每个 row/query.

重复此过程超过 600 次是不可行的(并且不可能,考虑到 BigQuery 的子查询限制)

我想不出一种方法来自动执行此查询,甚至想不出其他方法来解除这么多单元格的嵌套(我的 SQL 知识到此为止)。

有没有什么方法可以使用 SQL/BigQuery 查询对 600 多列进行这样的取消测试?以更有效的方式更可取?如果没有,我正在考虑使用从 BigTable 到 BigQuery 的简单 Python 连接器进行每日批处理,但我担心这会产生费用。

任何文档、参考或想法将不胜感激。

谢谢。

一般来说,当您尝试使用 SQL 查询 NoSQL 数据库(如 BigTable)时,您将陷入痛苦的境地。取消嵌套数据在 SQL 中是一项非常昂贵的操作,因为每次调用 UNNEST 时你都在有效地执行交叉连接(即 many-to-many),所以尝试这样做 600 多次会给你一个查询超时或巨额账单。

BigTable API 将比 SQL 更有效,因为它旨在查询 NoSQL 结构。一个常见的模式是每天运行一个脚本(例如 Cloud Functions 中的 Python 脚本)并使用 API 获取当天的数据,解析它,然后将其输出到文件在云存储中。然后您可以根据需要通过 BigQuery 查询这些文件。循环遍历所有数据列而不需要大量数据转换的每日脚本通常很便宜,而且绝对比试图强制它通过 SQL.

更便宜

也就是说,如果您真的打算使用 SQL,您也许可以使用 BigQuery 的 JSON functions 来提取您需要的嵌套数据。如果没有示例数据,很难想象您的数据结构是什么,但您可以将整行作为 JSON 的单列或字符串来读取。然后,如果您有要提取的值的 predictable 路径,则可以使用 JSON_EXTRACT_STRING_ARRAY 之类的函数将所有这些值提取到一个数组中。 Regex 函数也可以类似地使用。但是如果你需要在整体上做这种解析table才能查询,那么先进行数据转换的批处理作业仍然会更有效率。