Firestoreからたくさんのデータを取得してたくさんのデータを書き込むのに使えそうな関数
6887 ワード
500件以上取得する可能性のあるクエリで取得したドキュメントをコピーしたいときがあったので作りました。一応テストもしたのでちゃんと動きます。
import { firestore } from "firebase-admin"
const db = firestore()
/// batchExecutorに最大500件ずつSnapShotを渡してくれる
/// 注意:
/// queryにはorderつけて渡すこと(query.startAtがうまく動かなさそうなので)
/// await batch.commit() はbatchExecutor内で呼ばないとデータ処理されない
export async function executeInBatch(query: firestore.Query, batchExecutor: (batch: firestore.WriteBatch, snapshot: firestore.QueryDocumentSnapshot[]) => Promise<void>): Promise<void> {
const BATCH_LIMIT = 500
let hasNextPage = true
let lastDocument: firestore.DocumentSnapshot | undefined
while (hasNextPage) {
// 1件多めに取得して次がまだあるか判断する
let q = query.limit(BATCH_LIMIT + 1)
if (lastDocument) {
// 前回の続きから取得
q = q.startAt(lastDocument)
}
const snapshot = await q.get()
// 取得できた件数が指定通りだったら次のデータがまだある
hasNextPage = snapshot.size === (BATCH_LIMIT + 1)
// snapshot.docsをpopしても要素が消えないのでコピーした配列に対して操作する
const docs = snapshot.docs.concat()
if (hasNextPage) {
// 続きから取得する用に1件とっておく
lastDocument = docs.pop()
}
// batch処理してもらう
await batchExecutor(db.batch(), docs)
}
}
// 使い方
const query = db.collection("users").order("createdAt", "desc")
await executeInBatch(query, async (batch, documents) => {
documents.forEach(doc => {
batch.set(db.collection("samples").doc(), { name: doc.name })
})
await batch.commit()
})
Author And Source
この問題について(Firestoreからたくさんのデータを取得してたくさんのデータを書き込むのに使えそうな関数), 我々は、より多くの情報をここで見つけました https://qiita.com/_mogaming/items/25a996fd45fece6296b0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .