【问题标题】:How to avoid N + 1 queries in Firestore?如何避免 Firestore 中的 N + 1 个查询?
【发布时间】:2020-02-17 02:20:57
【问题描述】:

是否有类似于 Mongodb 中的“填充”方法并包含在 Rails 中,可以填充与其他文档关联的文档 ID,而不是我必须遍历每个文档并进行单独的查询。

例如,假设我有一个组文档,其中包含一个名为 members 的集合。该集合中的每个文档都对应于用户文档的 ID。有什么方法可以填充这些文档中的每一个,而无需我实际进行单独的查询来提取每个 ID 的用户文档。

【问题讨论】:

  • 您是否找到任何解决方案或解决此问题的方法?我也面临同样的问题

标签: algorithm firebase google-cloud-firestore


【解决方案1】:

如果您想更新集合中文档的内容,您必须查询每个文档,迭代它们,然后单独更新内容。 Firestore 中没有像 SQL 这样的“更新位置”功能,可让您在一次操作中更新多个文档。

【讨论】:

    【解决方案2】:

    有几个选项可以避免在 Firestore 中进行 N+1 查询 - 我正在考虑自己进一步测试这些

    1. 集合组查询 - 您可以根据名称检索特定的子集合,但一次只能检索一个。见Firestore query subcollections

    2. inarray-contains-any 查询 - 一次只能引用 10 个参考文档。 https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html

    3. 非规范化、本地化存储 - 您最多可以在单个 Firestore 文档中存储 1Mb,包括单个文本字段 - 例如,序列化 JSON。将相关文档数据存储在同一个文档中,并基于云功能批量更新。这将通过将数据聚集到第一个请求中来消除一些 N+1 查询。

    4. 辅助数据库 - 辅助数据存储(ElasticSearch、Solr 或 Algolia 等云搜索索引)可用于附加功能。您可以使用 in 类型查询来查找引用的对象 - 例如'返回所有具有这些 ID 的文档'。数据库应该以 JSON 样式的格式存储相同的字段。 您还可以使用缓存(Redis 或 Memcache)作为任何快速写入的临时数据存储,例如聚合计算(SUM、MAX、MIN)

      辅助数据库需要与 Firestore 同时更新,或者通过云函数触发器 (https://firebase.google.com/docs/functions/firestore-events) 近乎实时地捕获文档更改。

      出于安全原因,您可能希望通过服务器端云功能而不是直接通过客户端查询来执行此操作,具体取决于您的应用程序数据的敏感性以及它是否是多租户的。

    5. 预先计算的查询 - 您可以预先计算数据并将其存储在单独的文档中以便更快地访问,这在性质上类似于缓存。

      如果您等待第一次访问,那么第一次访问会比较慢,但是您可以确切地知道要为第 2 次、第 3 次和第 4 次访问缓存哪些数据。

      根据您的应用程序,您可能需要为所有潜在的未来查询存储大量数据,并在更改时保持更新。

    6. Firebase - 这具有不同的性能配置文件,并且可以并行运行,如选项 #4。

    我倾向于选择 #1 / #2(在可行的情况下)、#4 和 #3 的顺序,尽管 #4 的成本也可能要高得多。希望选项 #1 和 #2(本机功能)在未来得到扩展,以允许更多有用的变化或复杂的场景。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多