Google app engine 如何处理具有两个“属性”的实体;独特的;财产?

Google app engine 如何处理具有两个“属性”的实体;独特的;财产?,google-app-engine,google-cloud-datastore,Google App Engine,Google Cloud Datastore,考虑一个基于web的系统,其中多个用户可能同时创建帐户。系统要求用户具有唯一的用户名和唯一的电子邮件地址。在RDBMS中,这很简单:“email”字段将被标记为唯一。我怎样才能以数据存储的方式实现这一点 这是我最初的尝试: // Create entity using the username as key String username = ... // provided by the user String email = ... // provided by the user Ent

考虑一个基于web的系统,其中多个用户可能同时创建帐户。系统要求用户具有唯一的用户名和唯一的电子邮件地址。在RDBMS中,这很简单:“email”字段将被标记为唯一。我怎样才能以数据存储的方式实现这一点

这是我最初的尝试:

// Create entity using the username as key
String username = ... // provided by the user
String email = ...    // provided by the user
Entity entity = new Entity("Users", KeyFactory.createKey("User", username));
entity.setProperty("email", email);

// Create a query that matches the email property
Query q = new Query();
q.setFilter(new FilterPredicate("email", FilterOperator.EQUAL, email));

// Start a transaction
Transaction txn = datastore.beginTransaction();

try {
    // Try to get an entity with that username
    datastore.get(KeyFactory.createKey("User", username);
}
catch(EntityNotFoundException e) {
    // No entity with that username, make sure the e-mail
    // is not taken either
    PreparedQuery pq = datastore.prepare(q);
    if (pq.countEntities(FetchOptions.Builder.withLimit(1)) == 0) {
        // The e-mail isn't taken either, all good
        datastore.put(entity);
        txn.commit();

        ... handle success here ...

        return;
    }
}
finally {
    if (txn.isActive())
        txn.rollback();
}

... handle failure here ...
但经过几次简单的测试后,我注意到查询并不总是“看到”前不久所做的“卖出”(我应该猜到最终的一致性)。为了解决这个问题,我尝试将该查询转换为“虚拟”祖先查询

所以这个“虚拟”祖先查询是这样工作的。我创建了一个具有命名键的RootUser类型的实体。我从这个根用户那里获取密钥,并将其作为上面代码中查询的祖先密钥。现在这也不行了,我仍然收到重复的电子邮件地址。我还尝试配置事务,使其成为跨组事务,但这也没有帮助


那么,关于如何让它工作,有什么建议吗?可能吗?

快速版本:您希望使用另一个实体“种类”,并将您的唯一值存储为此类对象的id。例如,“User.username:myusername”,“User.email:email@example.com". 通过首先创建这些条目,您将知道值何时不是唯一的

请参见下面的示例实现。。

我试图避免这种情况,但我想这是唯一的办法。谢谢