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();