在dynamodb预期的约束,以防止重复

我是DynamoDB的新手,我无法在node.js和DynamoDB中使用以下scheme:

我想插入一个用户在用户表中,但我不希望这个成功,如果用户的电子邮件地址已经存在。

以下代码能够成功插入新用户:

var item = { id: { S: uuid.v4()}, email: { S: 'my@email.com' } }; dynamodb.putItem({ TableName: 'user', Item: item, Expected: { email: { Exists: false } } }, function (err, data) { if (err) { return callback(err); } callback(); }); 

我认为预期值会通过引发ConditionalCheckFailedException错误来防止用户表中的重复电子邮件地址。 不是这种情况; 上面的代码将一致插入重复的电子邮件。 我尝试添加“ID”作为额外的预期字段,但这并没有改变行为。

当我修改代码的时候,我得到一个ConditionalCheckFailedException,所以ID是固定的,而不是生成的UUID;

 var item = { id: { S: 'Test' }, email: { S: 'my@email.com' } }; 

我应该解释一下,'id'是散列键,'email'是范围键。

这种行为使我相信这些约束只能在用散列键指定的logging上工作。 如果是这样的话,那么AWS的文档确实会让人感到困惑(我用粗体突出了什么让我感到困惑):

如果Exists为false,则Amazon DynamoDB假定表中不存在该属性值。 如果实际上该值不存在,那么假设是有效的,并且操作成功。 如果find该值,尽pipe假设它不存在,则操作失败,并出现ConditionalCheckFailedException。

假设文件是​​正确的,我一定是做错了什么? 任何帮助将非常感激!

编辑2013年11月9日

根据下面的评论,我决定改变战术。 我有点不情愿使用一个值,我需要引用大多数其他领域的对象是不可改变的。 我现在有一个电子邮件地址表,充当用户ID的查找/索引表。 这使我可以很容易地让用户更改他或她的电子邮件地址(我甚至可以支持多个电子邮件地址)。

谢谢您的帮助!

带有范围键的DynamoDB表中的项目是散列键和范围键的组合,在mysql中是一种唯一的(id,email)。 所以在第一种方法中,当你插入一个已经存在于表中的用户时,你正在创build一个全新的项目,因为uuid是完全不同的:

第一项 – >哈希键:7f224b97-c144-4df2-bc3e-cfba69d5bc6e,范围键:my@email.com

第二项 – >哈希键:34cc6d26-dce4-4eb4-afec-3a382d9579fc,范围键:my@email.com

所以Expected条件确实是有效的,但是表中没有其他哈希键7f224b97-c144-4df2-bc3e-cfba69d5bc6e的项目有一个Range key = my@email.com,put项目成功。

如果你真的想保证用户电子邮件的唯一性,你应该把它作为表的哈希键。 当你想要查询用户时,它也会让你更容易:如你所知,要在DynamoDB中执行一个查询,你必须指定你想查询的哈希键的确切值,如果你不知道这个值你正在寻找的散列键,你将不得不执行表扫描(效率更低)。

所以,如果你使用uuid作为哈希键,你将不得不使用表扫描来检索你的用户(我假设你不知道与你想从数据库中检索的用户关联的uuid)。 如果您使用用户邮件作为哈希键,您将能够使用查询检索它们。

希望能帮助到你!