🔥

firestoreのバッチ書き込み

2021/02/25に公開

概要

最近firestoreをいじっている中で、バッチ書き込みという処理を書く機会があったのでメモ

バッチ書き込みとは

  • 完全には理解していないが、大量のデータを応答性よく書き込みができるっぽい
  • 通常の書き込み処理を何回も繰り返すと、そのたびにリクエストを送ることになるが、バッチ書き込みでは書き込みのリクエストは1回で済む
  • また、同時に大量の書き込みができる
  • 同じようなものにトランザクションというのがあるようだが、今回は割愛
  • ちなみにfirestoreの場合、同時書き込みできる件数は上限500件までのようなので、それ以上処理する場合はバッチを分けないといけなさそう

コード例

  // バッチインスタンス作成
  var batch = firebase.firestore().batch();
  // ユーザーID(仮)
  var uid = '001';
  var myUid = '002';
  // ユーザードキュメントの参照作成
  var userRef = firebase.firestore().collection('users').doc(uid);
  var userOpts = {
    followersCount: firebase.firestore.FieldValue.increment(1.0),
  };
  // update
  batch.update(userRef, userOpts);

  // 参照作成
  var followersRef = firebase.firestore().collection('users').doc(uid).collection('followers').doc(myUid);
  var followersOpts = {
    createdAt: firebase.firestore.FieldValue.serverTimestamp(),
    user_id : myUid
  };
  // set
  batch.set(followersRef, followersOpts);

  // バッチ書き込み処理
  await batch.commit();

解説

  • 上記では、SNSのようなサービスで、フォローした時の処理の一部分を例として書いてみた
  • 上記例では二箇所のドキュメントに同時に書き込みをしている
  • usersコレクションのドキュメントID001に対してフォロワー数をインクリメントする書き込みと、同ユーザーのサブコレクションであるfollowersコレクションに、自身のUIDをドキュメントIDにしてデータを書き込んでいる
  • これらは片方だけ処理されるとデータに不整合が起きかねないので、バッチ書き込みしたかった
  • もう少し詳細なコードの説明は下記の通り

firebase.firestore().batch()

  • ここでbatchインスタンスを作成している
  • このインスタンスを使ってsetやらupdateやらdeleteやらをしていく

batch.update(userRef, userOpts);

  • 上記で説明した通り、作成したbatchインスタンスを使ってuserRefの箇所にuserOptsの情報を書き込んでいる
  • 書き方としては通常の書き込み処理と同じような感じではある
  • ちなみに処理としてはドキュメントを指定する必要があるので、set, update, deleteは使えるがaddは使えない

batch.commit();

  • バッチ書き込みする処理を登録し終えたら、まとめて書き込みをするためこちらのコードを入力する
  • こうすることで一度でリクエストでまとめての処理ができる

まとめ

  • 架空の例なので実際に動かしているところはお見せできないのですが、だいたいこんな感じで動くと思います。
  • その他firestoreのルールでバッチ書き込みの時に使えるgetAfter関数とかがあったり、いろいろとできることがあります
  • 最初はバッチ書き込みは失敗して欲しくない処理をまとめてやってくれるものという認識だったのですがどうやらその一面は機能のほんの一部でしかなく、どちらかというと書き込みリクエストが1回で済むという側面の方が価値があるようです
  • 最近バックエンドの勉強もするようになったので、そういう部分について知れるのは面白い

Discussion