在我的数据库中,有一个项目(type: 'TOTAL'
)告诉我有多少种特定类型(type: 'CONFIG'
)的项目。删除CONFIG
项时,我想减少存储在TOTAL
中的数字。 TOTAL
不一定存在,所以我想将其设置为0(如果不存在),或者将其从当前值中减去1。
if total exists
total = total - 1
else
new total = 0
我正在使用UpdateItem,因为在运行此查询之前我没有关于TOTAL
项目的任何信息。如果我使用ADD并且TOTAL
还不存在,它将把值设置为0,然后减去1,而不是像我想要的那样将其设置为0。我尝试将SET与if_not_exists一起使用,但是在该项目确实存在的情况下(即当我希望它减去1时),它不会使用操作数。
这是我当前的查询,当我调用该函数以删除CONFIG
项时运行该查询:
aws dynamodb update-item \
--table-name application \
--key '{"type":{"S":"TOTAL"},"id":{"S":"CONFIG"}}' \
--update-expression "SET TotalConfigs = if_not_exists(TotalConfigs-1,:z)" \
--expression-attribute-values '{":z":{"N":"0"}}'
我得到的错误是
An error occurred (ValidationException) when calling the UpdateItem operation:
Invalid UpdateExpression: Syntax error; token: "-", near: "TotalConfigs-1"
对此我并不感到惊讶,因为我知道它不会起作用。有没有一种方法可以执行我想做的事而无需使用多个查询?
答案 0 :(得分:1)
最安全,最有效的方法是使用transactions。您将有一个包含两个操作的事务,一个将是带有新项的PUT,另一个是将total
用于Atomic Counters的UPDATE
答案 1 :(得分:1)
按照OP的问题模式,使用单个查询就可以做到这一点:
aws dynamodb update-item \
--table-name 'application' \
--key '{"type":{"S":"TOTAL"},"id":{"S":"CONFIG"}}' \
--update-expression "SET TotalConfigs = if_not_exists(TotalConfigs, :one) - :incr" \
--expression-attribute-values '{":one":{"N":"1"}, ":incr":{"N":"1"}}'
这将在0(或1-1)处启动TotalConfig,并且使用相同查询进行后续更新会将TotalConfig减少1。