【问题标题】:Query BigQuery nested/repeated fields查询 BigQuery 嵌套/重复字段
【发布时间】:2016-07-17 18:09:56
【问题描述】:

我是 BigQuery(和 sql)的新手,我正在尝试设置一个表,其中每行包含一个 message 列(字符串)和 metadata 列(重复)。我想使用元数据列,以便查询与某些元数据参数匹配的消息。

比如我的消息字符串是:

Hi honey, I'm home!

元数据列是描述消息的任意键/值对:

{"category": "personal", "message_type": "salutation"}

这将允许我要求 bigquery:

将所有包含category 或personal 的消息返回给我(或message_type 或personal 等)

重申一下,对于插入的每个消息行,元数据键都可能不同(例如,新行的元数据键可能是 favorite_color 而不是 category)。

为了支持我想要的元数据灵活性,这是我提出的架构:

[
{"name": "message", "type": "string", "mode": "required"}
{"name": "metadata", "type": "record", "mode": "repeated", "fields": [ {"name": "key", 
                                                                        "type": "string", 
                                                                        "mode": "required"},
                                                                       {"name": "value", 
                                                                        "type": "string", 
                                                                        "mode": "required"}]}
]

架构要求每个元数据条目/行都包含一个名为 key 的列和一个名为 value 的列。它似乎工作正常。

有趣的是,Bigquery 将我的消息行表示为两行(我猜这被称为“扁平化”?):

message                 | metadata_key    |    metadata_value
------------------------------------------------------------
Hi honey, I'm home!       category             personal
Hi honey, I'm home!       message_type         salutation

我想出了如何查询单个元数据值,例如 category=personal:

SELECT * FROM [table.test] 
WHERE
metadata.key="category" AND metadata.value="personal"

我得到一个单行返回:

message                 | metadata_key    |    metadata_value
------------------------------------------------------------
Hi honey, I'm home!       category             personal

这太棒了!但是,我不知道如何构造一个与多个元数据参数匹配的更复杂的查询,例如:

获取所有包含category 的personal 和message_type 的salutation 的消息

以下查询不返回任何内容:

SELECT * FROM [table.test] 
WHERE
metadata.key="category" AND metadata.value="personal" AND
metadata.key="message_type" AND metadata.value="salutation" 

我认为这是因为 bigquery 将我的单个消息行分解为两行(每个嵌套元数据行一个)。这显然意味着我的查询将永远无法匹配单行,因为我试图匹配两个不同的元数据行(即我要求 metadata.key 同时等于两个不同的值,并且元数据.value 同时等于不同的值)。所以我对如何适当地构建我的查询感到有些困惑。

理想情况下,我希望 BigQuery 返回一个单个行(我开始使用的原始示例行),因为它满足我查询的两个元数据要求。

我假设我需要 GROUP BY、FLATTEN、WITHIN、unflatten 等的某种组合。可能性/结构的组合对于这个 sql/bigquery 新手来说有些令人生畏。任何帮助表示赞赏:)

【问题讨论】:

    标签: sql nested metadata google-bigquery


    【解决方案1】:

    试试下面 - 只是选项之一
    它总结了每行中有多少个“匹配项,如果全部(在这种情况下 - 2)输出它。非常简单

    SELECT *, 
    SUM((metadata.key="category" AND metadata.value="personal")
     OR (metadata.key="message_type" AND metadata.value="salutation")
    ) WITHIN RECORD AS check,
    FROM [table.test] 
    HAVING check = 2
    

    更简洁的版本如下

    SELECT * 
    FROM [table.test]
    OMIT RECORD IF 
    SUM((metadata.key="category" AND metadata.value="personal")
     OR (metadata.key="message_type" AND metadata.value="salutation")
    ) != 2    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多