LoginSignup
0
1

More than 1 year has passed since last update.

Firestoreでドキュメントに一括で書き込む(500件を超える場合にも対応)

Last updated at Posted at 2023-01-30

batch処理で一括書き込みできる

Firestore の batch write を使用することで、500件ずつのドキュメントの更新を行うことができます。以下は Node.js でのサンプルコードです。

const admin = require('firebase-admin');

admin.initializeApp();
const firestore = admin.firestore();

async function updateDocuments(collectionName, batchSize = 500) {
  const collectionRef = firestore.collection(collectionName);
  const query = collectionRef.orderBy('timestamp').limit(batchSize);
  const documents = await query.get();
  
  let batch = firestore.batch();
  documents.forEach(document => {
    batch.update(document.ref, { isProcessed: true });
  });
  
  return batch.commit();
}

500件を超える場合もbatch処理の繰り返し

Firestore の batch write は一度に最大 500 件までのドキュメントを更新することができます。500 件を超えるドキュメントの更新を行いたい場合は、複数の batch write を繰り返すことで対応することができます。以下は Node.js でのサンプルコードです。

const admin = require('firebase-admin');

admin.initializeApp();
const firestore = admin.firestore();

async function updateDocuments(collectionName, batchSize = 500) {
  const collectionRef = firestore.collection(collectionName);
  let query = collectionRef.orderBy('timestamp').limit(batchSize);
  let documents = await query.get();

  while (documents.size > 0) {
    let batch = firestore.batch();
    documents.forEach(document => {
      batch.update(document.ref, { isProcessed: true });
    });

    await batch.commit();

    // 次の batch 取得用に query の条件を更新
    query = collectionRef.orderBy('timestamp')
      .startAfter(documents.docs[documents.docs.length - 1])
      .limit(batchSize);
    documents = await query.get();
  }
}

timestamp順にbatch writeを使用して500件以上のドキュメントを一括で更新することができます。

サブコレクションのドキュメントを更新する

Firebase Admin SDKで実際にFirestoreのドキュメントを一括更新してみます。
チーム(teams)コレクションのサブコレクション(memberships)のドキュメントを一括更新します。

const admin = require("firebase-admin");
const serviceAccount = require("./hoge.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

async function main() {
    console.log("***処理開始***メンバーシップにfooを追加する");

    //チームを取得
    const teamCol = await admin.firestore().collection("teams").get();
    teamCol.forEach(async team => {
        //メンバーシップを取得
        let membershipCol = team.ref.collection("memberships");
        let query = membershipCol.limit(500);
        let documents = await query.get();

        while (documents.size > 0) {
            let batch = admin.firestore().batch();
            
            documents.forEach(document => {
                batch.update(document.ref, {
                    foo: "hoge"
                });
            });

            await batch.commit();

            query = membershipCol.startAfter(documents.docs[documents.docs.length -1]).limit(500);
            documents = await query.get();
        }
    });

    console.log("***処理終了***メンバーシップにfooを追加する");
}

main().then();
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1