如何在DynamoDB的Map类型字段中新增属性而非替换
问题
现有数据库结构如下:
{"email":"example@mail.com","products": {"product1":{"price":"$10","details":"detail"},"product2":{"price":"$20","details":"detail"}}}
希望向products这个Map类型字段中新增属性,期望输出:
{"email":"example@mail.com","products": {"product1":{"price":"$10","details":"detail"},"product2":{"price":"$20","details":"detail"},"product3":{"price":"$10","details":"detail"}}}
当前使用API Gateway的UpdateItem操作,映射模板如下:
{"TableName": "tableName","Key": {"email": {"S": "$input.path('$.email')"}},"UpdateExpression": "SET #pr = :vals","ExpressionAttributeNames": {"#pr": "products"},"ExpressionAttributeValues": {":vals": {"M": {"$input.path('$.productId')": {"M": {"price": {"N": "$input.path('$.price')"},"details": {"S": "$input.path('$.details')"}}}}}},"ReturnValues": "NONE"}
使用该模板会直接替换整个products字段,实际输出变成:
{"email":"example@mail.com","products": {"product3":{"price":"$10","details":"detail"}}}
请问如何向Map中新增属性而非替换整个Map?
解决方案
问题出在你的UpdateExpression直接赋值给了整个products字段,导致原有数据被覆盖。要给Map类型字段新增属性,需要使用点标记法指定要新增的Map子属性,而非替换整个Map。
修改后的映射模板如下:
{ "TableName": "tableName", "Key": {"email": {"S": "$input.path('$.email')"}}, "UpdateExpression": "SET #pr.#pid = :prod", "ExpressionAttributeNames": { "#pr": "products", "#pid": "$input.path('$.productId')" }, "ExpressionAttributeValues": { ":prod": { "M": { "price": {"S": "$input.path('$.price')"}, "details": {"S": "$input.path('$.details')"} } } }, "ReturnValues": "NONE" }
关键修改点说明:
- UpdateExpression:改为
SET #pr.#pid = :prod,其中#pr指向products,#pid指向要新增的产品ID,仅给productsMap新增指定子属性,不会覆盖原有内容。 - ExpressionAttributeNames:新增
#pid动态引用传入的productId,避免直接在表达式中使用变量引发语法问题。 - ExpressionAttributeValues:
:prod仅传入新增的单个产品数据,而非整个productsMap。 - 注意:如果你的
price是带$的字符串类型(如示例中的$10),需把原模板中的{"N": ...}改成{"S": ...},因为N类型是纯数字,不能包含符号,否则会报错。
内容的提问来源于stack exchange,提问作者Jess
相关产品推荐
相关产品推荐

