【目次】
フィールド created_at
の順番に処理をしていきます。
const admin = require('firebase-admin');
const firebaseApp= initializeApp({
credential: cert(serviceAccount),
databaseURL: "https://foo.firebaseio.com"
}, "firebaseApp");
const db = getFirestore(firebaseApp)
/**
* Firestore コレクションのドキュメントをバッチ処理で更新します。
* Firestore のバッチ書き込みは一度に最大 500 件のドキュメント更新を許可します。この関数は、500 件を超えるドキュメントをシーケンシャルに処理することで対応します。
*
* @param {string} collectionName - 更新する Firestore コレクションの名前。
* @param {Object} updatingFieldAndValue - 各ドキュメントで更新するフィールドについて、キーと値のペアのオブジェクトとして指定。
* @param {number} [batchSize=500] - 各バッチで更新する最大ドキュメント数。デフォルトは 500。
* @returns {Promise<void>} - すべてのバッチが処理されたときに解決する Promise。
* @throws Firestore 操作に問題が発生した場合にエラーをスローします。
*/
async function updateDocumentsInBatches(collectionName, updatingFieldAndValue, batchSize = 500) {
try {
// コレクション参照を取得
const collectionRef = db.collection(collectionName);
// 並び替えに使うフィールド名
const orderField= 'created_at';
// 最初のバッチを取得するためのクエリを作成
let query = collectionRef.orderBy(orderField).limit(batchSize);
let documents = await query.get();
// 更新された合計数
let totalUpdatedCount = 0;
// ドキュメントが存在する間ループを続ける
while (documents.size > 0) {
// バッチを作成
let batch = firestore.batch();
// 各ドキュメントを更新
documents.forEach(document => {
batch.update(document.ref, updatingFieldAndValue);
});
// バッチをコミット
await batch.commit();
// 更新された合計数を更新
totalUpdatedCount += documents.size;
console.log(`バッチ更新: ${documents.size} 件のドキュメントを更新しました。`);
// 次のバッチのドキュメントを取得するためにクエリを更新
query = collectionRef.orderBy(orderField)
.startAfter(documents.docs[documents.docs.length - 1])
.limit(batchSize);
documents = await query.get();
}
// 更新成功のログメッセージ
console.log(`コレクション ${collectionName} のドキュメントを正常に更新しました。合計: ${totalUpdatedCount} 件のドキュメントを更新しました。`);
} catch (error) {
throw error;
}
}
下記のように使います。
// 使用例: todosというコレクションのドキュメントのstatusをdoneに更新する
updateDocumentsInBatches('todos', { status: 'done' });