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 メッセージ内の数値フィールドで、SUMAVGMINMAXCOUNT などの集計関数を使用できます。

次のクエリは、テーブル内のすべてのアルバムの平均リリース年を計算します。

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;

次のステップ