【问题标题】:How can I update a large number of documents in my Firestore database?如何更新 Firestore 数据库中的大量文档?
【发布时间】:2021-08-21 04:11:42
【问题描述】:

背景

我是一名年轻的开发人员,仍在攻读本科课程,因此如果我显得无知,请提前道歉。我是,我正在学习,这个解决方案正在测试我的能力。这很有趣,但希望我能得到一些帮助。

目标

我需要更新我的 Firestore 集合中的每个文档。每个文档都需要来自其相应用户文档的附加数据。

例如: 需要更新的文档包含“John”和“Amanda”的 uid。 我需要在他们的共享文档中添加其他字段,即他们的每个“全名”:“John Adams”和“Amanda Smith”

更新前:

{
  "Document"
    "userA": "John",
    "userB": "Amanda"
}

更新后:

{
  "Document"
    "userA": "John",
    "userAFull": "John Adams",
    "userB": "Amanda",
    "userBFull": "Amanda Smith"
}

接近

由于我必须更新集合中的每个文档(大约 20k 个文档),我决定使用链式批处理写入来编写云函数来解决这个问题,这样所有请求都不必通过 Firestore API,例如客户端读写。

这是我在创建函数时参考的材料:

Chained Batched writes

Get Data From Single Document Firestore Typescript

Firestore JavaScipt SDK

Returning multiple values in Tpyescript

Firestore Batched writes documentation

这是我的代码有错误:

export const updateFollowersSchema = functions
  .runWith({ timeoutSeconds: 600 })
  .https.onRequest(async (req,res) => {
    const query = await db.collection('Followers')
    query.get()
      .then(query => {
        if (query.empty){
          return null;
        } else {
          const batchArray: any[] = []
          batchArray.push(db.batch())
          let operationCounter = 0;
          let batchIndex = 0;

          query.forEach(async document => {
            const fromUserFullname = await getFromInfo(document)
            const [forUserFullname, forUserProfileImageURL] = await getForInfo(document)
            batchArray[batchIndex].update(document.ref, { 
                fromUserFullname: fromUserFullname,
                forUserFullname: forUserFullname,
                forUserProfileImageURL: forUserProfileImageURL
            })
            operationCounter++

            if(operationCounter == 499){
              batchArray.push(db.batch())
              batchIndex++
              operationCounter = 0
            }
          });

          batchArray.forEach(async batch => await batch.comit)
          return
        }
      })
  })
async function getFromInfo(data: Document){
  const userQuery = await db.collection('users').doc(data.uid).get()
  return userQuery.fullname;
}
async function getForInfo(data: Document){
  const userQuery = await db.collection('users').doc(data.uid).get()
  return [userQuery.fullname, userQuery.profileImageURL];
}

上下文

profileImageURL 是存储用户个人资料的用户文档字段

fullname是存储用户全名的用户文档字段

问题

  • 我的方法是否正确/可行?还是有更好的方法?
  • 将文档数据传递给异步函数以便从相应用户那里获取数据的语法是什么
  • 我使用 await 和 async 函数的方法是否能够正确处理必须查询用户数据以填充 fromUserFullname 和我正在编写的其他对象的线程问题?

【问题讨论】:

标签: typescript google-cloud-firestore google-cloud-functions


【解决方案1】:

乍一看还不错,但我建议更改一下:

batchArray.forEach(async batch => await batch.comit)

收件人:

Promise.all(batchArray.map(batch => batch.commit()))

所以这个:

  • comit 中删除拼写错误,并添加括号来调用它。
  • 停止等待每个单独的事务,允许它们并行运行。

另见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-16
    • 2020-02-01
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2020-12-21
    相关资源
    最近更新 更多