Siva
Siva

Reputation: 1148

Uniqueness check with a query in cloud firestore in datastore mode

As the cloud firestore in datastore mode supports strong consistency for all queries,

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

could this be used to check for uniqueness? Say I have a user entity (top level entity) that has a datastore allocated ID as the key. In the past, it wasn't possible to do a query by email within the transaction as it was a global query. But it seems that it is now possible to do such queries as clarified at

New Google Cloud Firestore in Datastore mode Queries Clarification

Does this mean it is now possible to ensure there are no duplicate User entities by just indexing and querying by the email property within the transaction to insert the User entity?

My current implementation is to have a separate entity that has a named key using the email and do a key based query on that entity within the transaction. I can get rid of that if I can query by email on the User entity itself within the transaction and it guarantees duplicate entities won't be created under race condition.

Upvotes: 0

Views: 265

Answers (2)

Siva
Siva

Reputation: 1148

After some research, below is all I could gather.

  1. Even though datastore mode is strongly consistent, it is still not possible to use Global queries within transactions.
  2. As per https://cloud.google.com/datastore/docs/concepts/entities#creating_an_entity , it is possible to use a transaction, do get and based on the result do put but this is only possible with the uniqueness on the key.
  3. There are some strategies outlined at Google cloud datastore only store unique entity for this same issue and Dan suggested "insert" as opposed to "put". At first I didn't get this as Appengine Datastore api never had "Insert". But the Cloud Datastore Client API has Mutations which allow explicit insert (as opposed to put which maps to Upsert).
  4. As a result of the mutation support, I could use the same strategy of using a separate entity (different Kind) with key that maps to the unique property (such as email) but avoid an extra Get in the transaction. I do tx.Mutate on both the user entity and the uniqueness tracking entity with Named key on the email and try to insert both. This results in AlreadyExists error which can be used to track the violation.

Upvotes: 1

Maximus Macdonald
Maximus Macdonald

Reputation: 171

As of right now, 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.

Upvotes: 0

Related Questions