【问题标题】:What is the best way to perform Firebase updates for large collections via cloud?通过云为大型集合执行 Firebase 更新的最佳方式是什么?
【发布时间】:2020-10-08 16:23:54
【问题描述】:

假设集合大小为 +100k 文档,那么更新所有文档的最有效方法是什么?

我们正在讨论一个数据库范围的更新过程,我需要读取每个文档,根据特定规则添加/删除一些字段,然后将文档中更新的字段写回集合。并对所有文档重复此过程。

理想情况下,我希望能够在云中完成。事实证明,使用我的本地计算机在花费多少时间和增加内存负载方面存在问题。

由于内存限制 (2gb) 和 9 分钟的超时限制,即使使用批量写入,云函数似乎也不是一个好方法...

【问题讨论】:

  • 你看过this answer吗,它解决了一个类似的问题,并补充了 Edmund 的评论
  • @Edgardo 是的,我有,但问题不相似:我的问题与批量写入方面无关(如该答案所示),而是与可以管理此操作的方式有关以基于云的方式。

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


【解决方案1】:

这绝对可以通过云功能完成。

除非您尝试一次查询整个集合,否则我认为您不应该遇到内存限制。使用paginated querying 限制一次读取的文档数量,然后循环浏览页面。

选项 1

绕过超时限制的一种快速方法是使用pub/sub trigger 云函数。当您的函数即将超时时,只需将其发布到自己的发布/订阅主题即可触发自身再次运行。但是请确保一旦不再有要更新的文档,您的函数就会停止发布,否则它会陷入无限循环。

选项 2

如果您需要极快地执行此更新任务,您可以使用如下所示的分而治之的策略。

[Fn A] =publish=to=> [Pub/Sub] =trigger=> [Fn B], [Fn B], [Fn B], [Fn B] 。 . .

云函数 A 使用分页查询来查询集合,页面大小为 N。将每个页面上第一个文档的 uid 和 N 的值发布到 pub/sub 主题。

编写一个由该发布/订阅主题触发的云函数 B。它将从 pub/sub 读取文档 uid 和编号 N。它将使用该文档 uid 作为起点,然后更新接下来的 N 个文档。该函数会被并行触发多次。 Fn A 的每个 pub/sub 发布一次。您选择的 N 将影响将生成的函数 B 的实例数。

【讨论】:

  • 感谢@Edmund 的回答。对于选项 1,假设我正在使用分页查询,您如何建议让函数的新实例知道旧实例停止的位置?并且在批次中间的情况下会发生什么?
  • 我会编写查询,使其仅返回尚未更新的文档。这样,您的函数总是可以从查询返回的文档列表的开头开始。这可以通过将where() 函数添加到您的查询来完成。例如:``` lang-js query = db.collection("cities") .where("population", ">", 100000) .orderBy("population") .limit(5000); ```
  • 感谢您的澄清。不过,这在我的情况下不起作用,因为我只会在检索并执行计算后才知道是否需要更新文档;在这种情况下where() 没有帮助。所以我相信只有选项 2 是可行的,我会尝试一下。
  • 如果您不能在选项 1 中使用 where() 也没关系。在这种情况下,您可以让您的云函数将它更新到 pub/sub 的最后一个文档的 uid 发布。那么云函数的下一次调用将知道上一次调用在哪里停止。
猜你喜欢
  • 2012-02-28
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
相关资源
最近更新 更多