protobuf データをクエリする
このドキュメントでは、Bigtable に保存されているプロトコル バッファ(protobuf)データの読み取りとクエリの一般的なクエリ パターンの例を示します。
このページを読む前に、次のことを理解しておいてください。
データの例
次の例では、アルバムとアーティストに関する情報を格納する Music テーブルを使用します。データは、列修飾子 album を持つ album_details という名前の列ファミリーに保存されます。列修飾子には 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"
}
クエリの例
次の例は、Bigtable と BigQuery の外部テーブルで GoogleSQL を使用して 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 の JSON 列として protobuf データをクエリできます。
次のクエリは、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;