DynamoDB - 如何使用 updateItem 更新嵌套对象
Posted
技术标签:
【中文标题】DynamoDB - 如何使用 updateItem 更新嵌套对象【英文标题】:DynamoDB - How to upsert nested objects with updateItem 【发布时间】:2021-12-24 15:08:55 【问题描述】:您好,我是 dynamoDB 的新手。下面是发电机表的架构
"user_id":1, // partition key
"dob":"1991-09-12", // sort key
"movies_watched":
"1":
"movie_name":"twilight",
"movie_released_year":"1990",
"movie_genre":"action"
,
"2":
"movie_name":"harry potter",
"movie_released_year":"1996",
"movie_genre":"action"
,
"3":
"movie_name":"lalaland",
"movie_released_year":"1998",
"movie_genre":"action"
,
"4":
"movie_name":"serendipity",
"movie_released_year":"1999",
"movie_genre":"action"
..... 6 more attributes
如果项目(带有 dob 的用户 ID)不存在,我想插入一个新项目,否则通过检查电影是否尚不可用 movies_watched
地图将电影添加到现有的 movies_watched
地图。
目前,我正在尝试使用update(params)
方法。
以下是我的方法:
function getInsertQuery (item)
const exp =
UpdateExpression: 'set',
ExpressionAttributeNames: ,
ExpressionAttributeValues:
Object.entries(item).forEach(([key, item]) =>
if (key !== 'user_id' && key !== 'dob' && key !== 'movies_watched')
exp.UpdateExpression += ` #$key = :$key,`
exp.ExpressionAttributeNames[`#$key`] = key
exp.ExpressionAttributeValues[`:$key`] = item
)
let i = 0
Object.entries(item. movies_watched).forEach(([key, item]) =>
exp.UpdateExpression += ` movies_watched.#uniqueID$i = :uniqueID$i,`
exp.ExpressionAttributeNames[`#uniqueID$i`] = key
exp.ExpressionAttributeValues[`:uniqueID$i`] = item
i++
)
exp.UpdateExpression = exp.UpdateExpression.slice(0, -1)
return exp
上述方法只是为所有***属性以及嵌套属性(带有文档路径)创建具有表达式名称和值的更新表达式。
如果该项目已经通过更新movies_watched
地图可用,则效果很好。但是如果该项目不可用并且在插入时抛出异常。以下是例外:
The document path provided in the update expression is invalid for update
但是,我仍然不确定如何在 movies_watched 地图中检查重复的电影
有人可以指导我正确的方向吗,非常感谢任何帮助!
提前致谢
【问题讨论】:
【参考方案1】:根据您的模型,如果在更新之前不从 DDB 读取项目,则无法执行此操作(此时该过程很简单)。如果您不想将这种额外的读取容量强加到您的表上以进行更新,那么您需要重新设计您的数据模型:
您可以将 movies_watched 更改为 Set 并保存对电影的引用。需要注意的是,Set 只能包含数字或字符串,因此您将拥有电影 ID 或名称,或者将数据保留为您的 Set 中的 JSON 字符串,然后在读取时将其解析回 JSON。使用 SET,您可以对 movies_watched 属性执行 ADD 操作。 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.ADD
您可以采用单表设计方法,并使用(PK:userId 和 SK:movie_id)将这些电影作为单独的项目观看。要获取用户,您将执行查询并仅指定 PK=userId -> 您将获得一个集合,其中一个项目是您的用户记录,其他项目是 movies_watched。如果您是 DynamoDB 的新手并且正在学习其中的技巧,那么我建议您采用这种方法。 https://www.alexdebrie.com/posts/dynamodb-single-table/
【讨论】:
以上是关于DynamoDB - 如何使用 updateItem 更新嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 AWS Lambda 按名称查询 dynamoDB 表
AWS SDK JavaScript v3 / 如何在 dynamoDB 扫描命令中使用 ExpressionAttributeNames?