Amazon dynamodb DynamoDB-如果散列(或散列和范围组合)不';不存在
以下是我的用例:我有一个带有哈希+范围键的Dynamo表。当我将新项目放入表中时,我想进行唯一性检查。有时我想保证散列是唯一的(忽略范围)。其他时候,我希望允许重复哈希,但要保证哈希和范围的组合是唯一的。我怎样才能做到这一点 我尝试了属性_not_exists。它似乎处理第二种情况,即检查哈希+键组合。下面是一个PHP示例:Amazon dynamodb DynamoDB-如果散列(或散列和范围组合)不';不存在,amazon-dynamodb,Amazon Dynamodb,以下是我的用例:我有一个带有哈希+范围键的Dynamo表。当我将新项目放入表中时,我想进行唯一性检查。有时我想保证散列是唯一的(忽略范围)。其他时候,我希望允许重复哈希,但要保证哈希和范围的组合是唯一的。我怎样才能做到这一点 我尝试了属性_not_exists。它似乎处理第二种情况,即检查哈希+键组合。下面是一个PHP示例: $client->putItem(数组)( “TableName”=>“test”, 'Item'=>数组( 'hash'=>array('S'=>abcdefg'), '
$client->putItem(数组)(
“TableName”=>“test”,
'Item'=>数组(
'hash'=>array('S'=>abcdefg'),
'range'=>array('S'=>'some other value'),
'任意'=>数组('N'=>233)
),
'ConditionExpression'=>'属性不存在(哈希)'
));
奇怪的是,如果我使用属性不存在(散列)
或属性不存在(范围)
,这似乎并不重要。他们似乎做了完全相同的事情。这就是它的工作原理吗
知道如何处理我只想检查
散列
的唯一性的情况吗?你不能。DynamoDB中的所有项都通过它们的散列
或散列
+范围
(取决于您的表)进行索引
一种对目前情况的总结:
- 一个散列键可以有多个范围键
- 每个项都有一个
和一个散列
键范围
- 您正在发出一个
请求,并且必须提供PutItem
散列和
范围
- 您在
或散列
属性名称上提供了一个范围
,其中条件表达式
属性不存在
条件只是检查具有该名称的属性是否存在,它不关心该值attribute\u not\u exists
哈希表开始:
hash=A,range=1
hash=A,range=2
有四种可能的情况:
如果您尝试放置具有hash=A,range=3且属性不存在(hash)
的项,则PutItem
将成功,因为属性不存在(hash)
的计算结果为true
。不存在键为hash=A、范围为3且满足属性不存在(hash)
条件的项
如果尝试放置具有hash=A、range=3和attribute\u not\u exists(range)
的项,则PutItem
将成功,因为attribute\u not\u exists(range)
计算结果为true
。不存在满足属性\u不存在(范围)
条件的键为hash=A,范围为3的项
如果您尝试放置具有hash=A、range=1且属性不存在(hash)
的项,则PutItem
将失败,因为属性不存在(hash)
的计算结果为false
。存在键为hash=A,范围为1的项,该项不满足属性不存在(hash)
的条件
如果尝试放置具有hash=A、range=1和attribute\u not\u exists(range)
的项,则PutItem
将失败,因为attribute\u not\u exists(range)
计算结果为false
。存在一个项,其键hash=A,范围=1
不满足属性\u不存在(范围)
的条件
这意味着将发生以下两种情况之一:
数据库中存在散列
+范围
对。
属性不存在(散列)
必须为true
属性不存在(范围)
必须为true
数据库中不存在散列
+范围
对。
属性不存在(散列)
必须为false
属性不存在(范围)
必须为false
在这两种情况下,无论是将结果放在散列还是范围键上,都会得到相同的结果。散列
+范围
键标识整个表中的单个项,并对该项评估您的条件
您正在有效地执行“如果具有此哈希
+范围
键的项不存在,则放置此项”。如果表具有哈希和范围,则可以使用和操作
“ConditionExpression”=>“attribute_not_exists(散列)和attribute_not_exists(范围)”此版本的解释是,搜索将查找与提供的散列键匹配的项,然后仅检查该记录中是否存在该属性。我想,如果你有一个散列和一个范围键,它也应该是一样的
如果请求尝试查找具有哈希键的现有项
“b825501b-60d3-4e53-b737-02645d27c2ae”。如果这是第一次使用此id
正在使用中,将没有现有项目,并且
“属性\不\存在(电子邮件)”将计算为true,将请求放入
通过
如果已使用此id,则将存在一个现有项。然后
条件表达式将在中查找现有的电子邮件属性
现有项,如果存在电子邮件属性,则Put请求将
失败,如果没有电子邮件属性,Put请求将通过
无论哪种方式,它都不会比较“email”属性的值和
不检查表中的其他项目是否使用相同的“电子邮件”值
如果电子邮件是散列键,则请求将尝试查找现有的
“具有哈希键的项”tielur@example.me".
如果存在具有相同电子邮件值的其他项目,则现有项目将被删除
找到了。自从电子邮件
$client->putItem(array(
'TableName' => 'test',
'Item' => array(
'hash' => array('S' => 'abcdefg'),
'range' => array('S' => 'some other value'),
'whatever' => array('N' => 233)
),
'ConditionExpression' => 'attribute_not_exists(#h) AND attribute_not_exists(#r)',
'ExpressionAttributeNames' => array('#h' => 'hash', '#r' => 'range')
));
$client->putItem(
'TableName' => 'test',
'Item' => array(
'hash' => array('S' => 'abcdefg'),
'range' => array('S' => 'some other value'),
'whatever' => array('N' => 233)
),
'ConditionExpression' => 'attribute_not_exists(#h)',
'ExpressionAttributeNames' => array('#h' => 'hash')
));
val item = Item().withPrimaryKey(...).withString(...)
val putItemSpec = PutItemSpec().withItem(item)
.withConditionExpression("attribute_not_exists(DocId)")
table.putItem(putItemSpec)
@DynamoDBTable(tableName = "Docs")
class Docs {
// Partition key
@get:DynamoDBHashKey(attributeName = "DocId")
var docId: String? = null
}
val doc = Docs().apply {
docId = "myId"
}
val mapper = DynamoDBMapper(AmazonDynamoDBClientBuilder.defaultClient())
// As suggested by http://rrevo.github.io/2018/03/09/dynamo-no-update/
val ifDocIdNotExists = DynamoDBSaveExpression().apply {
expected = mapOf("DocId" to ExpectedAttributeValue().apply {
isExists = false
})
}
mapper.save(doc, ifDocIdNotExists)