【问题标题】:Update values in separate Collections with Firestore in a denormalised DB使用非规范化数据库中的 Firestore 更新单独集合中的值
【发布时间】:2019-04-24 12:13:08
【问题描述】:

我有两个收藏:

Collection c1
-- doc1
-- -- name: "doc1Name"
-- -- position: 1
-- doc2
-- -- name: "doc2Name"
-- -- position: 2

Collection c2
-- doc1
-- -- name: "name1"
-- -- reference: "doc1Name"
-- -- position: 1
-- doc2
-- -- name: "name2"
-- -- reference: "doc2Name"
-- -- position: 2
-- doc3
-- -- name: "name3"
-- -- reference: "doc2Name"
-- -- position: 2

如果有人设置了c1.doc2.position = 3,我也需要将c2.doc2.positionc2.doc3.position 更新为3。

但是,Firestore 不允许根据给定条件更新字段,因此我需要迭代属于 c2 的所有文档,并在 reference = "doc2Name" 时更新 position 字段。如果我使用批量写入或事务,我无法在他们的正文中查询C2,因为如果我这样做,Firestore 会返回类似“事务已经完成。”的错误,因为侦听器的异步性质。而且我无法更新完成处理程序中的两个集合之一,因为如果第二个批处理/事务失败,这会使数据库不一致。

这是处理非规范化数据库时的典型场景,非规范化在处理 Firestore 时也很常见。 Firestore 有没有不涉及云功能的解决方案?

【问题讨论】:

  • 批量写入前不能查询吗? (仅供参考,Firestore 的名称中没有大写的 S。)
  • 您的意思是保存所有要编辑的文档的引用的查询?如果是这样的话,我可以,但是如果在延迟期间集合的内容发生变化,我仍然会出现不一致(我编辑了大写的 S)。

标签: database firebase transactions google-cloud-firestore consistency


【解决方案1】:

您不能对某些查询的动态结果进行原子处理或批处理。您必须能够在交易或批次开始之前识别所有文件。无论您是从移动客户端还是服务器(包括 Cloud Functions,它也可能处理超出您预期顺序的事件),您都会遇到此问题。

假设它们不改变大小,您唯一的选择可能是对两个集合的全部内容进行交易。如果集合可以随时更改大小,那么我认为此特定模型不适用于您的用例,因为无法锁定整个数据库以防止发生冲突更改。

【讨论】:

  • 是的,批量更新必须涉及两个集合的全部内容(实际上它们并没有那么大)。我必须说,我的用例(即以原子方式更新两个可能会改变大小的引用集合)对我来说听起来并不那么具体。
  • 这是一个常见的请求,但今天仍然不可能。实际上,文档位于不同的集合中并不重要——您仍然必须识别所有文档才能进行原子更改。随时提交功能请求。 support.google.com/firebase/contact/support?page=bug_or_feature
  • 我明白了。感谢您的宝贵时间。
猜你喜欢
  • 2014-11-01
  • 2011-09-24
  • 2016-10-22
  • 2017-10-23
  • 2018-05-31
  • 2012-11-18
  • 2010-10-06
  • 2017-03-01
  • 2016-07-23
相关资源
最近更新 更多