Java
google
GoogleCloudPlatform
GoogleBigQuery
bigquery

BigQueryでクライアントライブラリを利用してデータをSELECTする

Google BigQueryでは、テーブルからデータを取得する方法として以下の2つがあります。

  • クライアントライブラリを利用して取得する方法
  • APIを利用して取得する方法

本記事では、「クライアントライブラリを利用して取得する方法」を紹介します。

環境

  • クライアントライブラリ:0.32.0-beta
  • java:8

環境構築

BigQueryのクライアントライブラリのインストールを参照。
2018年1月時点で、javaのクライアントライブラリはbeta版しかないので、本記事でもそれを利用します。なお、クライアントライブラリのソースは以下で公開されています。
https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master/google-cloud-bigquery

テーブル構成

本記事では、以下の構成のテーブルに対してSELECTします。

  • データセット名:dev1
  • テーブル名:names_2014
  • スキーマ情報:以下の通り
COLUMN TYPE MODE
name STRING NULLABLE
gender STRING NULLABLE
count INTEGER NULLABLE

listTableDataメソッドを利用する

BigQuery#listTableDataを利用します。

BigQuerySelectSample.java
package bigquery.sample;

import com.google.api.gax.paging.Page;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.FieldValueList;

public class BigQuerySelectSample {

    private static final String DATASET_NAME = "dev1";
    private static final String TABLE_NAME = "names_2014";
    private static final int NAME_COLUMN = 0;
    private static final int GENDER_COLUMN = 1;

    public static void main(String[] args) {

        BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

        // use listTableData method
        Page<FieldValueList> tableData = bigquery.listTableData(DATASET_NAME, TABLE_NAME);
        for (FieldValueList row : tableData.iterateAll()) {
            System.out.println(row.get(NAME_COLUMN).getValue() + " " + row.get(GENDER_COLUMN).getValue());
        }
    }
}

listTableDataメソッドは、スキーマ情報(カラム名等)は返さずデータのみを返します。そのため、ある特定のカラムのデータが必要な時は、row.get(0)、row.get(1)のように、rowのindexでアクセスする必要があります。

queryメソッドを利用する

BigQuery#listTableDataの他に、BigQuery#queryを利用することもできます。

BigQuerySelectSample.java
package bigquery.sample;

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.FieldValueList;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.QueryResponse;

public class BigQuerySelectSample {

    private static final String DATASET_NAME = "dev1";
    private static final String TABLE_NAME = "names_2014";

    public static void main(String[] args) throws InterruptedException {

        BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

        // use query method
        String query = "SELECT name, gender FROM `" + DATASET_NAME + "." + TABLE_NAME + "` WHERE name = 'Ryder'";
        QueryJobConfiguration queryConfig = QueryJobConfiguration.of(query);
        QueryResponse response = bigquery.query(queryConfig);
        for (FieldValueList row : response.getResult().iterateAll()) {
            System.out.println(row.get("name").getValue() + " " + row.get("gender").getValue());
        }
    }
}

BigQueryでもRDBと同じような形式でSQLを書くことができます。なお、詳細なクエリリファレンスはBigQueryのSELECT句になります。queryメソッドは、スキーマ情報(カラム名等)も返してくれるので、row.get("columnName")のようにカラム名でのアクセスが可能となります。

パフォーマンス

簡易計測になりますが、33206件のテーブルに対してBigQuery#listTableData、BigQuery#queryともに約4~5秒でした。両者ともにそこまで大差はなさそうです。

以上です。

参考