0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Firestoreからたくさんのデータを取得してたくさんのデータを書き込むのに使えそうな関数

Last updated at Posted at 2019-10-25

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()
})
0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?