クエリ結果のページ分割

このドキュメントでは、BigQuery REST API を使用してクエリ結果のページ分割を行う方法について説明します。

API を使用した結果のページ分割

すべての collection.list メソッドから返される結果は、特定の状況下でページ分割されます。ページあたりの結果の数は maxResults プロパティによって制御されます。

メソッド ページ分割基準 maxResults のデフォルト値 maxResults の最大値
Tabledata.list レスポンス サイズがシリアル化された JSON で 10 MB を超える場合、または maxResults 行を超える場合は、ページ分割された結果を返します。 100,000 100,000
その他すべての collection.list メソッド レスポンスが maxResults 行を超える場合、ページ分割された結果を返します。 50 1,000

maxResults を上記の最大値より大きい値に設定すると、結果は最大値に基づいてページ分割されます。

ページは全行数のサブセットです。1 ページ分のデータを超える場合、結果データは pageToken プロパティを持ちます。次のページの結果を取得するには、別の list 呼び出しを行い、トークン値を pageToken という名前の URL パラメータとして指定します。

テーブルデータのページ分割に使用する bigquery.tabledata.list メソッドは行オフセット値またはページトークンを使用します。詳しくは、テーブルデータの閲覧をご覧ください。

BigQuery の結果をページ分割するサンプルを以下に示します。

C#

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用にある C# 向けの手順に従って設定を行ってください。詳細については、BigQuery C# API のリファレンス ドキュメントをご覧ください。

using Google.Api.Gax;
using Google.Apis.Bigquery.v2.Data;
using Google.Cloud.BigQuery.V2;
using System;
using System.Collections.Generic;
using System.Linq;

public class BigQueryBrowseTable
{
    public void BrowseTable(
        string projectId = "your-project-id"
    )
    {
        BigQueryClient client = BigQueryClient.Create(projectId);
        TableReference tableReference = new TableReference()
        {
            TableId = "shakespeare",
            DatasetId = "samples",
            ProjectId = "bigquery-public-data"
        };
        // Load all rows from a table
        PagedEnumerable<TableDataList, BigQueryRow> result = client.ListRows(
            tableReference: tableReference,
            schema: null
        );
        // Print the first 10 rows
        foreach (BigQueryRow row in result.Take(10))
        {
            Console.WriteLine($"{row["corpus"]}: {row["word_count"]}");
        }
    }
}

Java

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用にある Java 向けの手順に従って設定を行ってください。詳細については、BigQuery Java API のリファレンス ドキュメントをご覧ください。

TableId tableIdObject = TableId.of(datasetName, tableName);
// This example reads the result 100 rows per RPC call. If there's no need to limit the number,
// simply omit the option.
TableResult tableData =
    bigquery.listTableData(tableIdObject, TableDataListOption.pageSize(100));
for (FieldValueList row : tableData.iterateAll()) {
  // do something with the row
}

Go

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用の Go 向けの手順に従って設定を行ってください。詳細については、BigQuery Go API のリファレンス ドキュメントをご覧ください。

Go 用の Google Cloud クライアント ライブラリでは、デフォルトで自動的に結果がページ分割されるため、ページ分割のためのコードを記述する必要はありません。次に例を示します。

table := client.Dataset(datasetID).Table(tableID)
it := table.Read(ctx)
for {
	var row []bigquery.Value
	err := it.Next(&row)
	if err == iterator.Done {
		break
	}
	if err != nil {
		return err
	}
	fmt.Println(row)
}

Node.js

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用にある Node.js 向けの手順に従って設定を行ってください。詳細については、BigQuery Node.js API のリファレンス ドキュメントをご覧ください。

Node.js 用の Google Cloud クライアント ライブラリでは、デフォルトで自動的に結果がページ分割されるため、ページ分割のためのコードを記述する必要はありません。次に例を示します。

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const datasetId = "my_dataset";
// const tableId = "my_table";

async function browseRows() {
  // Displays rows from "my_table" in "my_dataset".

  // Create a client
  const bigqueryClient = new BigQuery();

  // List rows in the table
  const [rows] = await bigqueryClient
    .dataset(datasetId)
    .table(tableId)
    .getRows();

  console.log('Rows:');
  rows.forEach(row => console.log(row));
}

browseRows();

PHP

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用にある PHP 向けの手順に従って設定を行ってください。詳細については、BigQuery PHP API のリファレンス ドキュメントをご覧ください。

PHP 用の Google Cloud クライアント ライブラリでジェネレータ関数 rows を使用すると、ページが自動的に分割されます。この関数は反復処理中に次の結果ページをフェッチします。

use Google\Cloud\BigQuery\BigQueryClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $datasetId = 'The BigQuery dataset ID';
// $tableId   = 'The BigQuery table ID';
// $maxResults = 10;

$maxResults = 10;
$startIndex = 0;

$options = [
    'maxResults' => $maxResults,
    'startIndex' => $startIndex
];
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);
$numRows = 0;
foreach ($table->rows($options) as $row) {
    print('---');
    foreach ($row as $column => $value) {
        printf('%s: %s' . PHP_EOL, $column, $value);
    }
    $numRows++;
}

Python

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用にある Python 向けの手順に従って設定を行ってください。詳細については、BigQuery Python API のリファレンス ドキュメントをご覧ください。

Python 用 Google Cloud クライアント ライブラリは、デフォルトで自動的にページ分割を行います。そのため、自分でページ分割を実装する必要はありません。次に例を示します。

# from google.cloud import bigquery
# client = bigquery.Client()

dataset_ref = client.dataset("samples", project="bigquery-public-data")
table_ref = dataset_ref.table("shakespeare")
table = client.get_table(table_ref)  # API call

# Load all rows from a table
rows = client.list_rows(table)
assert len(list(rows)) == table.num_rows

# Load the first 10 rows
rows = client.list_rows(table, max_results=10)
assert len(list(rows)) == 10

# Specify selected fields to limit the results to certain columns
fields = table.schema[:2]  # first two columns
rows = client.list_rows(table, selected_fields=fields, max_results=10)
assert len(rows.schema) == 2
assert len(list(rows)) == 10

# Use the start index to load an arbitrary portion of the table
rows = client.list_rows(table, start_index=10, max_results=10)

# Print row data in tabular format
format_string = "{!s:<16} " * len(rows.schema)
field_names = [field.name for field in rows.schema]
print(format_string.format(*field_names))  # prints column headers
for row in rows:
    print(format_string.format(*row))  # prints row data

Ruby

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用にある Ruby 向けの手順に従って設定を行ってください。詳細については、BigQuery Ruby API のリファレンス ドキュメントをご覧ください。

Ruby 用 Google Cloud クライアント ライブラリTable#dataData#next を使用すると、ページ分割が自動的に行われます。

require "google/cloud/bigquery"

def browse_table
  bigquery = Google::Cloud::Bigquery.new project_id: "bigquery-public-data"
  dataset  = bigquery.dataset "samples"
  table    = dataset.table "shakespeare"

  # Load all rows from a table
  rows = table.data

  # Load the first 10 rows
  rows = table.data max: 10

  # Print row data
  rows.each { |row| puts row }
end

任意のページのリクエストと、冗長リスト呼び出しの回避

前のページに戻る場合、またはキャッシュされた pageToken の値を使用して任意のページにジャンプする場合、ページのデータが最後に表示された後で変更されている可能性がありますが、データが変更されたことは明確には示されません。これを確認するには、ETag プロパティを使用できます。

すべての collection.list メソッド(Tabledata 用を除く)は、結果で Etag プロパティを返します。このプロパティは、ページが最後のリクエスト以降に変更されているかどうかを確認するために使用できるページ結果のハッシュです。ETag 値を使用して BigQuery にリクエストを行うと、BigQuery は ETag 値と API によって返された ETag 値を比較し、ETag 値が一致しているかどうかに基づいて応答します。次の方法で、冗長なリスト呼び出しを回避するために ETag を使用できます。

  • 値が変更されている場合にのみリスト値を返す場合:

    値が変更されている場合にのみリスト値のページを返す場合は、HTTP の "If-None-Match" ヘッダーを使用し、保存しておいた ETag を指定してリスト呼び出しを行うことができます。指定した ETag がサーバー上の ETag と一致しない場合、BigQuery は、新しいリスト値のページを返します。Etag が一致する場合、BigQuery は HTTP 304 "変更されていません" 結果を返し、値を返しません。この例として、ユーザーが BigQuery に格納されている情報を定期的に入力するウェブページがあります。ETag と If-None-Match ヘッダーを使用することにより、データに変更がない場合に冗長なリスト呼び出しを避けることができます。

  • 値が変更されていない場合にのみリスト値を返す場合:

    リストの値が変更されていない場合にのみリスト値のページを返す場合は、HTTP の "if-match" ヘッダーを使用できます。BigQuery は、ETag 値を比較し、結果が変更されていない場合は結果のページを返します。ページが変更されている場合は、412 "前提条件失敗" を返します。

注: Etag は冗長なリスト呼び出しを避けるために有効な方法ですが、同じ方法を使用して、いずれかのオブジェクトが変更されたかどうかを確認できます。たとえば、特定のテーブルに対する get リクエストを実行し、ETag を使用して、テーブルが完全なレスポンスを返す前に変更されているかどうかを判断できます。


このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。