在数据存储模式下使用 Cloud Firestore 中的查询进行唯一性检查

Uniqueness check with a query in cloud firestore in datastore mode

由于数据存储模式下的云 Firestore 支持所有查询的强一致性,

https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode

这可以用来检查唯一性吗?假设我有一个用户实体(顶级实体),它以数据存储区分配的 ID 作为键。过去,不可能在交易中通过电子邮件进行查询,因为它是全局查询。但现在似乎可以进行在

处阐明的此类查询

这是否意味着现在可以通过在交易中通过电子邮件 属性 进行索引和查询以插入用户实体来确保没有重复的用户实体?

我当前的实现是使用电子邮件拥有一个具有命名键的单独实体,并在交易中对该实体执行基于键的查询。如果我可以在交易中通过电子邮件查询用户实体本身,我就可以摆脱它,并且它保证不会在竞争条件下创建重复的实体。

截至目前,there is no way to enforce uniqueness on a property. However, there are workarounds for what you are trying to do. One workaround is explained in the article linked above, and another is here

经过一些研究,以下是我能收集到的所有信息。

  1. 即使数据存储模式是强一致的,仍然无法在事务中使用全局查询。
  2. 根据 https://cloud.google.com/datastore/docs/concepts/entities#creating_an_entity ,可以使用事务,获取并根据结果进行放置,但这只有在密钥具有唯一性的情况下才有可能。
  3. 针对同一问题,Google cloud datastore only store unique entity 中概述了一些策略,Dan 建议 "insert" 而不是 "put"。起初我没有得到这个,因为 Appengine Datastore api 从来没有 "Insert"。但是 Cloud Datastore Client API 具有允许显式插入的 Mutations(而不是将映射映射到 Upsert)。
  4. 由于突变支持,我可以使用相同的策略,即使用单独的实体(不同种类),其键映射到唯一 属性(例如电子邮件),但避免额外的 Get在交易中。我在电子邮件上使用命名键对用户实体和唯一性跟踪实体执行 tx.Mutate 并尝试插入两者。这会导致可用于跟踪违规的 AlreadyExists 错误。