在 DynamoDB 中使用更新表达式
UpdateItem 操作会更新现有项目,或者将新项目添加到表中(如果该新项目尚不存在)。您必须提供要更新的项目的键。您还必须提供更新表达式,指示您要修改的属性以及要分配给这些属性的值。
更新表达式 指定 UpdateItem 将如何修改项目的属性,例如,设置标量值或者删除列表或映射中的元素。
下面是更新表达式的语法摘要。
update-expression ::= [ SETaction[,action] ... ] [ REMOVEaction[,action] ...] [ ADDaction[,action] ... ] [ DELETEaction[,action] ...]
更新表达式包含一个或多个子句。每个子句以 SET、REMOVE、ADD 或 DELETE 关键字开头。您可在更新表达式中按任意顺序包含其中任意子句。但是,每个操作关键字只能出现一次。
每个子句中存在一个或多个操作,用逗号分隔。每个操作表示一个数据修改。
此部分中的示例基于在 DynamoDB 中使用投影表达式中所示的 ProductCatalog 项目。
以下主题介绍了 SET 操作的一些不同使用案例。
SET – 修改或添加项目属性
在更新表达式中使用 SET 操作可将一个或多个属性添加到项目。如果任意这些属性已存在,则将由新值覆盖。如果您要避免覆盖现有属性,则可以将 SET 与 if_not_exists 函数结合使用。if_not_exists 函数特定于 SET 操作,只能在更新表达式中使用。
当您使用 SET 更新列表元素时,将使用您指定的新数据替代该元素的内容。如果元素尚不存在,SET 会将新元素附加到列表的末尾。
如果在单个 SET 操作中添加多个元素,则元素会按照元素编号的顺序排序。
您还可使用 SET 来加或减 Number 类型的属性。要执行多个 SET 操作,请使用逗号分隔它们。
在以下语法摘要中:
-
path元素是项目的文档路径。 -
operand元素可以为项目的文档路径,或者为函数。
set-action ::=path= value value ::=operand|operand'+'operand|operand'-'operandoperand ::=path| function function ::=if_not_exists (path, value)
如果项目在指定路径中不包含属性,则 if_not_exists 的求值结果为 value。否则,它的求值结果为 path。
以下 PutItem 操作创建将在示例中引用的示例项目。
aws dynamodb put-item \ --table-name ProductCatalog \ --item file://item.json
--item 的参数存储在 item.json 文件中。(为简单起见,仅使用了几个项目属性。)
{ "Id": {"N": "789"}, "ProductCategory": {"S": "Home Improvement"}, "Price": {"N": "52"}, "InStock": {"BOOL": true}, "Brand": {"S": "Acme"} }
修改属性
例
更新 ProductCategory 和 Price 属性。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET ProductCategory = :c, Price = :p" \ --expression-attribute-values file://values.json \ --return-values ALL_NEW
--expression-attribute-values 的参数存储在 values.json 文件中。
{ ":c": { "S": "Hardware" }, ":p": { "N": "60" } }
注意
在 UpdateItem 操作中,--return-values ALL_NEW 将导致 DynamoDB 按更新后的情况返回项目。
添加列表和映射
例
添加新列表和新映射。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET RelatedItems = :ri, ProductReviews = :pr" \ --expression-attribute-values file://values.json \ --return-values ALL_NEW
--expression-attribute-values 的参数存储在 values.json 文件中。
{ ":ri": { "L": [ { "S": "Hammer" } ] }, ":pr": { "M": { "FiveStar": { "L": [ { "S": "Best product ever!" } ] } } } }
将元素添加到列表
例
将新元素添加到 RelatedItems 列表。(请记住,列表元素从 0 开始,因此 [0] 表示列表中的第一个元素,[1] 表示第二个元素,依此类推。)
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET RelatedItems[1] = :ri" \ --expression-attribute-values file://values.json \ --return-values ALL_NEW
--expression-attribute-values 的参数存储在 values.json 文件中。
{ ":ri": { "S": "Nails" } }
注意
当您使用 SET 更新列表元素时,将使用您指定的新数据替代该元素的内容。如果元素尚不存在,SET 会将新元素附加到列表的末尾。
如果在单个 SET 操作中添加多个元素,则元素会按照元素编号的顺序排序。
添加嵌套映射属性
例
添加一些嵌套映射属性。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET #pr.#5star[1] = :r5, #pr.#3star = :r3" \ --expression-attribute-names file://names.json \ --expression-attribute-values file://values.json \ --return-values ALL_NEW
--expression-attribute-names 的参数存储在 names.json 文件中。
{ "#pr": "ProductReviews", "#5star": "FiveStar", "#3star": "ThreeStar" }
--expression-attribute-values 的参数存储在 values.json 文件中。
{ ":r5": { "S": "Very happy with my purchase" }, ":r3": { "L": [ { "S": "Just OK - not that great" } ] } }
对数值属性进行加减
您可以对现有数值属性执行加减运算。为此,请使用 +(加号)和 -(减号)运算符。
例
降低项目的 Price。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET Price = Price - :p" \ --expression-attribute-values '{":p": {"N":"15"}}' \ --return-values ALL_NEW
要提高 Price,请在更新表达式中使用 + 运算符。
将元素附加到列表
您可将元素添加到列表的末尾。为此,请将 SET 与 list_append 函数结合使用。(函数名区分大小写。) list_append 函数特定于 SET 操作,只能在更新表达式中使用。语法如下所示。
-
list_append (list1,list2)
该函数将选取两个列表作为输入,并将所有元素从 附加到 list2
。list1
例
在将元素添加到列表中,您创建 RelatedItems 列表并填充两个元素:Hammer 和 Nails。现在您将另外两个元素附加到 RelatedItems 的末尾。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET #ri = list_append(#ri, :vals)" \ --expression-attribute-names '{"#ri": "RelatedItems"}' \ --expression-attribute-values file://values.json \ --return-values ALL_NEW
--expression-attribute-values 的参数存储在 values.json 文件中。
{ ":vals": { "L": [ { "S": "Screwdriver" }, {"S": "Hacksaw" } ] } }
最后,您将另外一个元素添加到 RelatedItems 的 beginning。为此,请交换 list_append 元素的顺序。(请记住,list_append 将选取两个列表作为输入,并会将第二个列表附加到第一个列表。)
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET #ri = list_append(:vals, #ri)" \ --expression-attribute-names '{"#ri": "RelatedItems"}' \ --expression-attribute-values '{":vals": {"L": [ { "S": "Chisel" }]}}' \ --return-values ALL_NEW
生成的 RelatedItems 属性现在包含 5 个元素,其顺序如下:Chisel、Hammer、Nails、Screwdriver、Hacksaw。
防止覆盖现有属性
例
设置项目的 Price,但仅当项目还没有 Price 属性时设置。(如果 Price 已存在,则不执行任何操作。)
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET Price = if_not_exists(Price, :p)" \ --expression-attribute-values '{":p": {"N": "100"}}' \ --return-values ALL_NEW
REMOVE – 从项目中删除属性
在更新表达式中使用 REMOVE 操作可在 Amazon DynamoDB 中从某个项目删除一个或多个元素。要执行多个 REMOVE 操作,请使用逗号分隔它们。
下面是更新表达式中的 REMOVE 的语法摘要。唯一的操作数是您要删除的属性的文档路径。
remove-action ::=path
例
从项目中删除部分属性。(如果属性不存在,则不会执行任何操作。)
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "REMOVE Brand, InStock, QuantityOnHand" \ --return-values ALL_NEW
从列表中删除元素
您可使用 REMOVE 从列表中删除各个元素。
例
在将元素附加到列表中,您修改了列表属性 (RelatedItems),使它包含 5 个元素:
-
[0]—Chisel -
[1]—Hammer -
[2]—Nails -
[3]—Screwdriver -
[4]—Hacksaw
以下 Amazon Command Line Interface (Amazon CLI) 示例从列表中删除 Hammer 和 Nails。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "REMOVE RelatedItems[1], RelatedItems[2]" \ --return-values ALL_NEW
删除 Hammer 和 Nails 之后,剩下的元素将会移位。此列表现在包含以下元素:
-
[0]—Chisel -
[1]—Screwdriver -
[2]—Hacksaw
ADD – 更新数值和集
注意
一般而言,我们建议使用 SET 而不是 ADD。
在更新表达式中使用 ADD 操作可将新属性及其值添加到项目。
如果属性已存在,则 ADD 的行为取决于属性的数据类型:
-
如果属性是数字,并且添加的值也是数字,则该值将按数学运算与现有属性相加。(如果该值为负数,则从现有属性减去该值。)
-
如果属性是集合,并且您添加的值也是集合,则该值将附加到现有集合中。
注意
ADD 操作仅支持数字和集合数据类型。
要执行多个 ADD 操作,请使用逗号分隔它们。
在以下语法摘要中:
-
path元素是属性的文档路径。属性必须为Number或 set 数据类型。 -
value元素是要与属性相加的值(对于Number数据类型),或者是要附加到属性中的集合(对于 set 类型)。
add-action ::=pathvalue
以下主题介绍了 ADD 操作的一些不同使用案例。
添加数值
假设 QuantityOnHand 属性不存在。以下 Amazon CLI 示例会将 QuantityOnHand 设置为 5。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "ADD QuantityOnHand :q" \ --expression-attribute-values '{":q": {"N": "5"}}' \ --return-values ALL_NEW
既然 QuantityOnHand 存在,您可重新运行该示例以使 QuantityOnHand 每次增加 5。
将元素添加到集
假设 Color 属性不存在。以下 Amazon CLI 示例会将 Color 设置为包含两个元素的字符串集。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "ADD Color :c" \ --expression-attribute-values '{":c": {"SS":["Orange", "Purple"]}}' \ --return-values ALL_NEW
既然 Color 存在,您可向其添加更多元素。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "ADD Color :c" \ --expression-attribute-values '{":c": {"SS":["Yellow", "Green", "Blue"]}}' \ --return-values ALL_NEW
DELETE – 从集中删除元素
重要
DELETE 操作仅支持 Set 数据类型。
在更新表达式中使用 DELETE 操作可从集合中删除一个或多个元素。要执行多个 DELETE 操作,请使用逗号分隔它们。
在以下语法摘要中:
-
path元素是属性的文档路径。该属性必须是集数据类型。 -
子网是您要从path中删除的一个或多个元素。您必须指定subset作为集类型。
delete-action ::=pathsubset
例
在将元素添加到集中,您创建 Color 字符串集合。本示例将从该集合中删除部分元素。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "DELETE Color :p" \ --expression-attribute-values '{":p": {"SS": ["Yellow", "Purple"]}}' \ --return-values ALL_NEW
使用多个更新表达式
可以在单个语句中使用多个更新表达式。
如果要修改属性的值并彻底删除另一个属性,可以在单个语句中使用 SET 和 REMOVE 操作。此操作会将 Price 值降至 15,同时还会从项目中删除 InStock 属性。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET Price = Price - :p REMOVE InStock" \ --expression-attribute-values '{":p": {"N":"15"}}' \ --return-values ALL_NEW
如果您想在添加到列表的同时更改另一个属性的值,则可以在单个语句中使用两个 SET 操作。此操作会将 “Nails” 添加到 RelatedItems 列表属性中,并将 Price 值设置为 21。
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET RelatedItems[1] = :newValue, Price = :newPrice" \ --expression-attribute-values '{":newValue": {"S":"Nails"}, ":newPrice": {"N":"21"}}' \ --return-values ALL_NEW