在Google Datastore中唯一的电子邮件

huangapple go评论102阅读模式
英文:

Unique email in Google Datastore

问题

我有一个包含Email字段的User实体。User实体的ID是一个ULID,因为我想允许用户更改他们的电子邮件地址,但我希望确保电子邮件地址在CREATEUPDATE时都是唯一的。

我正在使用Datastore事务。这是一个代码片段:

ctx := context.Background()
k := datastore.NameKey("User", user.ID, nil)
_, err := client.RunInTransaction(ctx, func(t *datastore.Transaction) error {
    // 其他需要在事务中的操作
    _, err = t.Put(k, user)
    return err
})

return err

Email字段已经建立了索引。有没有办法在事务中搜索当前用户的电子邮件地址?

*datastore.Transaction没有GetAll方法,所以我无法像这样运行查询:

datastore.NewQuery("User").Filter("Email =", user.Email)

我担心使用

client.GetAll(ctx, q, nil)

不能保证在事务中的隔离性。

英文:

I have a User entity containing an Email field. The User entity id is a ULID, because I want to allow users to change their email addresses, but I want to ensure that the email address is unique on both a CREATE and an UPDATE.

I am using Datastore transactions. This is a code fragment:

ctx := context.Background()
k := datastore.NameKey("User", user.ID, nil)
_, err := client.RunInTransaction(ctx, func(t *datastore.Transaction) error {
    // other stuff that needs to be in transaction
	_, err = t.Put(k, user)
    return err
})

return err

The Email field is indexed. Is there any way to search the User entity for the current user's email address as part of the transaction?

*datastore.Transaction does not have a GetAll method, so I cannot run a query like this:

datastore.NewQuery("User").Filter("Email =", user.Email)

I'm afraid that using

client.GetAll(ctx, q, nil)

will not guarantee isolation within the transaction.

答案1

得分: 4

简短的回答是不可以,除非你查询的是特定的实体组,否则不能将查询作为事务的一部分。全局查询始终是最终一致的。然而,将所有内容放在一个单一的实体组中可能会严重限制写入吞吐量。

一种解决方法是创建另一个种类(Kind),其中的实体将电子邮件地址映射到用户。然后,在一个事务中,你可以检查电子邮件实体,如果它不存在或指向错误的位置,可以将电子邮件实体和用户实体一起设置为一个事务。

英文:

The short answer is no, you cannot use a query as part of a transaction unless you are querying a specific entity group. Global queries are alway eventually consistent. However, to put everything in a single entity group would likely limit write throughput too much.

A workaround is you can have another Kind with entities that map email addresses to users. Then you can, in a transaction, check the email Entity and if it doesn't exist or it points to a bad location, set the email Entity and the user Entity all as a single transaction.

huangapple
  • 本文由 发表于 2017年8月22日 22:43:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/45820737.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定