假设我在DynamoDB中存储具有以下结构的记录:
{
"id": "57cf5b43-f9ec-4796-9de6-6a50f556cfd8",
"created_at": "2015-09-18T13:27:00+12:00",
"count": 3
}
现在,是否可以在一个请求中实现以下目标:
id
的记录不存在,则应使用count = 1 id
的记录存在,则计数器正在更新。目前我正在进行查询以检查记录是否存在,并根据结果我执行put
或update
。把它折叠成一个单独的操作会很好。
答案 0 :(得分:16)
由于您的使用案例,您可以使用UpdateItem
API和UpdateExpression
执行此操作。由于此处的count
类型为Number
,因此您可以使用SET
或ADD
表达式:
ADD
的文档告诉您,您可以将其用于Number
类型(强调我的):
ADD - 如果该属性尚不存在,则将指定的值添加到项目中。如果该属性确实存在,则ADD的行为取决于属性的数据类型:
- 如果现有属性是数字,并且 Value 也是数字,则 Value 将以数学方式添加到现有属性中。如果 Value 是负数,则会从现有属性中减去它。
如果使用ADD递增或递减更新前不存在的项的数值,则DynamoDB使用0作为初始值。同样,如果对现有项使用ADD要更新或减少更新前不存在的属性值的项,DynamoDB使用0作为初始值。例如,假设您要更新的项目没有名为itemcount的属性,但您仍决定将数字3添加到此属性。 DynamoDB将创建itemcount属性,将其初始值设置为0,最后添加3。结果将是项目中的新itemcount属性,值为3.
对于您的示例,您可以让UpdateExpression
为ADD #c :n
,其中:n
的{{1}}类型为ExpressionAttributeValue
,Number
是值,1
#c
代替count
。您需要使用count
的占位符,因为它是ExpressionAttributeName
。
答案 1 :(得分:15)
在我的问题中我没有提到的是我希望count
在不修改created_at
的情况下进行后续事件。
我的最终工作UpdateInput看起来像这样:
{
Key: {
id: {
S: "some_unique_id"
}
},
TableName: "test",
ExpressionAttributeNames: {
#t: "created_at",
#c: "count"
},
ExpressionAttributeValues: {
:t: {
S: "2015-09-26T15:58:57+12:00"
},
:c: {
N: "1"
}
},
UpdateExpression: "SET #t = if_not_exists(#t, :t) ADD #c :c"
}