エクスポートされたFirestoreドキュメントをBigQueryに自動ロード
FirestoreドキュメントをBigQuery上でデータ分析する流れを円滑に
[2019年10月追記] Firebase Extensions の Export Collections to BigQueryが登場
2019年9月に Firebase Extensions が登場し、そこに含まれるExport Collections to BigQuery が、がほぼ上位互換かつお手軽です。
本記事のやり方のような一括エクスポート形式ではなく、Firestore のデータ変更がリアルタイムで蓄積されていきBigQueryのview機能で現時点の状態に対して分析できる作りになっています。まったく同じものではないため、細かい使い勝手やコスト面などで差異はあります。
以下、それが登場するまで一般的だった一括エクスポートのやり方です。
先日、Cloud Firestoreのドキュメントを gcloud
コマンドおよびREST API経由でエクスポート・インポートできるようになりました。
さらに、そのエクスポートされたドキュメントデータを、BigQueryにロードできるようになりました。
BigQueryへのロードは次の3通りのやり方がサポートされています。
- BigQueryのWeb UI
- コマンドライン(
bq
コマンド) - REST API
まずお手軽に試すには、BigQueryのWeb UIから手動実行するのが良いと思います。上のツイートのスクショ通りですが、ざっくり以下のような流れです。
- テーブル作成時に、Source DataにGCS(Google Cloud Storage)上のFirestoreエクスポートデータを指定してテーブル作成
- ロードジョブが発行されて、それが終わり次第テーブルが作成されて、BigQueryの強力なクエリでFirestoreドキュメントを分析できるようになる
この手作業を何度も繰り返すのは手間なので、本記事ではREST APIを使って、Firestoreドキュメントがエクスポートされたら自動的にBigQueryにロードするようにしてみます。
処理の流れ
処理の流れは以下のようになります。2つ目の手順が一番のポイントです。
- Firestoreのドキュメントをエクスポート
- GCSにエクスポートデータが作成されるので、それをトリガーにREST APIでBigQueryにロード
- ロードジョブが終わるとBigQueryテーブルが作成(すでにある場合は再生成)される
1. Firestoreのドキュメントをエクスポート
以下の説明などに従って、Firestoreのドキュメントをエクスポートします。
実行環境・条件などに応じて、gcloud
コマンド・REST APIからやりやすい方を選びます。
collection-ids
で指定したエクスポートデータのロードしかできないという制約に注意です。
If you plan to load a Cloud Firestore export into BigQuery, you must specify a
collection-ids
filter in your export command. Data exported without specifying a collection ID filter cannot be loaded into BigQuery.
gcloud
コマンドを使う場合、次のようになります。
gcloud alpha firestore export gs://[PROJECT_ID]-backups-firestore --collection-ids='users','messages'
バックアップ目的の場合、collection-ids
指定は通常しないはずですので、BigQueryへロードしたい場合は別途エクスポートが必要です。
(バックアップ目的とBigQueryロード目的を兼ねてcollection-ids
に全コレクションを列挙するというやり方もあり得るかもしれませんが、コレクション種類が増えた時にバックアップ漏れが発生するので少し危険だと思います。)
2. GCSにエクスポートデータが作成されるので、それをトリガーにREST APIでBigQueryにロード
Cloud Storage triggersを使います。
次のような関数を定義すると、GCSにエクスポートデータが作成されたのを検知して、BigQueryにそのロードジョブを発行することができます。
REST APIを叩いているところは、Google APIs Node.js ClientのBigQuery でできそうですが、エラーが出てうまく解決できなかったのでとりあえずREST APIを使うことにしました。
リクエストの body
が肝なので、SDKを使う場合でも上記コードは参考になるはずです。
以下のコマンドなどでデプロイします。
firebase deploy --only functions:onFirestoreBackupFinalize
このトリガーによって、今後 collection-ids
指定のFirestoreエクスポートがなされたら常に反応してBigQueryにロードしてしまうことに注意してください。コスト的には、Firestoreのエクスポートのドキュメント読み取り料金が支配的で、GCSからBigQueryへのロード料金はそれに比べてわずかであり、基本的には気にせずで良いと思います。
3. ロードジョブが終わるとBigQueryテーブルが作成(すでにある場合は再生成)される
手順1のエクスポートを実行すると、BigQueryのロードジョブが実行されます。
成功すると、上のコード例の場合はBigQueryの firestore
データセット上に users
や messsages
などエクスポートしたコレクション名と同じテーブルが作成されるはずです(データセットは予め作成しておいてください)。
この例の場合、テーブル名を常に同名として "writeDisposition": "WRITE_TRUNCATE"
で上書きするようになっていますが、テーブル名に日時など添えて常に新規で作るのもありだと思います(過去の時点でのデータ分析をしたい場合などに有効)。
次のようにFirestoreデータに対して、BigQueryの強力なクエリが投げられるようになりました🎉
これは単純な例ですが、複数コレクションをロードしてジョインするなど、思い通りのクエリを投げて高度なデータ分析が可能です。
注意としては、手順1でエクスポート指定した collection-ids
はサブコレクションも対象になることです。逆にいうと、コレクションがどの階層に属していても一括でエクスポートできるので便利です。BigQueryにロードしたあと、 __key__.path フィールドを見ると、どのコレクションに属しているのかを区別できます。
さらに、FirestoreドキュメントデータのBigQueryへのロードを定期実行したい場合は、以下と同様のやり方でできます。
アドホック分析用途では、定期実行の設定をせずとも必要なタイミングで手動で gcloud
コマンドによってFirestoreエクスポートをして、本記事で対応したBigQueryへの自動ロード結果を使って分析、という流れでも十分だとは思います。