查询 protobuf 数据
本文档提供了一些示例,演示了如何读取和查询存储在 Bigtable 中的协议缓冲区 (protobuf) 数据。
在阅读本页面内容之前,请先熟悉以下内容:
示例数据
以下示例使用存储专辑和艺术家信息的 Music 表。数据存储在名为 album_details 的列族中,并具有列限定符 album。列限定符包含 protobuf 消息。
protobuf 架构是在以下 proto 文件中定义的:
artist.proto:syntax = "proto3"; package package_name; message Artist { string name = 1; }album.proto:syntax = "proto3"; package package_name; import "artist.proto"; message Album { string title = 1; Artist artist = 2; int32 release_year = 3; }
因此,Bigtable 会为此表创建一个架构软件包,其中包含以下针对这些 protobuf 定义的描述符集:
file {
name: "artist.proto"
package: "package_name"
message_type {
name: "Artist"
field {
name: "name"
number: 1
label: LABEL_OPTIONAL
type: TYPE_STRING
json_name: "name"
}
}
syntax: "proto3"
}
file {
name: "album.proto"
package: "package_name"
dependency: "artist.proto"
message_type {
name: "Album"
field {
name: "title"
number: 1
label: LABEL_OPTIONAL
type: TYPE_STRING
json_name: "title"
}
field {
name: "artist"
number: 2
label: LABEL_OPTIONAL
type: TYPE_MESSAGE
type_name: ".package_name.Artist"
json_name: "artist"
}
field {
name: "release_year"
number: 3
label: LABEL_OPTIONAL
type: TYPE_INT32
json_name: "releaseYear"
}
}
syntax: "proto3"
}
示例查询
以下示例展示了如何使用 GoogleSQL 查询 Bigtable 和 BigQuery 外部表的 protobuf 数据。
将列转换为 protobuf 消息
您可以使用 CAST 运算符将 BYTES 值解释为 protobuf 消息。为此,您必须按照以下格式提供 protobuf 消息的完整名称:SCHEMA_BUNDLE_ID.FULLY_QUALIFIED_MESSAGE_NAME。
替换以下内容:
SCHEMA_BUNDLE_ID:您在创建架构包时为其分配的唯一 ID。FULLY_QUALIFIED_MESSAGE_NAME:消息的完整名称,必须包含在 proto 文件中定义的软件包名称,例如package_name.message_name。
以下示例查询将 album 列转换为 Album protobuf 消息。此消息在 package_name 软件包中定义,并且是名为 bundle_name 的架构软件包的一部分:
SELECT
CAST(album_details['album'] AS bundle_name.package_name.Album).title
FROM
Music;
访问嵌套字段
您可以使用点表示法访问 protobuf 消息中的嵌套字段。
以下查询从 Album 消息中的嵌套 Artist 消息检索艺术家的姓名:
SELECT
CAST(album_details['album'] AS bundle_name.package_name.Album).artist.name
FROM
Music;
根据 protobuf 字段进行过滤
您可以使用 WHERE 子句根据 protobuf 消息中字段的值过滤行。
以下查询会选择音乐人 Dana A. 的所有专辑:
SELECT
*
FROM
Music
WHERE
CAST(album_details['album'] AS bundle_name.package_name.Album).artist.name = 'Dana A.';
汇总 protobuf 字段
您可以在 protobuf 消息中使用 SUM、AVG、MIN、MAX 和 COUNT 等聚合函数来处理数字字段。
以下查询会计算表中所有专辑的平均发行年份:
SELECT
AVG(CAST(album_details['album'] AS bundle_name.package_name.Album).release_year)
FROM
Music;
按 protobuf 字段排序
您可以使用 ORDER BY 子句根据 protobuf 消息中的字段对结果集进行排序。
以下查询会检索所有专辑,并按发行年份以降序对其进行排序:
SELECT
*
FROM
Music
ORDER BY
CAST(album_details['album'] AS bundle_name.package_name.Album).release_year DESC;
与 BigQuery 外部表搭配使用
您可以创建外部表,以便从 BigQuery 查询存储在 Bigtable 中的 protobuf 数据。创建外部表时,您需要将列类型指定为 JSON,将其编码指定为 PROTO_BINARY,并将其与架构包相关联。此过程会将 protobuf 消息字节转换为等效的 JSON 数据,从而让您可以直接查询其字段。
以下是用于创建基于 Music 表的 BigQuery 外部表的表定义文件示例:
{
"sourceFormat": "BIGTABLE",
"sourceUris": [
"https://googleapis.com/bigtable/projects/PROJECT_ID/instances/INSTANCE_ID/tables/Music"
],
"bigtableOptions": {
"columnFamilies" : [
{
"familyId": "album_details",
"columns": [
{
"qualifierString": "album",
"type": "JSON",
"encoding": "PROTO_BINARY",
"protoConfig": {
"schemaBundleId": "bundle_name",
"protoMessageName": "package_name.Album"
}
}
]
}
]
}
}
创建外部表后,您可以在 BigQuery 中将 protobuf 数据作为 JSON 列进行查询。
以下查询从 BigQuery 外部表中检索 2022 年发行的所有专辑的标题:
SELECT JSON_VALUE(value, '$.title') AS title
FROM
`PROJECT_ID.DATASET.TABLE_NAME` AS t,
UNNEST(t.album_details.album.cell)
WHERE INT64(JSON_EXTRACT(value, '$.releaseYear')) = 2022;