如何在父节点可能不存在时条件更新DynamoDB中的嵌套列表
问题原因
报错是因为当客户条目完全不存在时,顶层的visits Map字段不存在,DynamoDB无法直接对visits.location53这个嵌套路径执行ADD操作,就会返回路径无效的异常。
解决方案
调整逻辑如下:
- 新增初始化
visitsMap的逻辑:在更新表达式中先用SET配合if_not_exists函数,保证即使条目不存在,也会先初始化visits为一个空Map,再执行后续ADD操作 - 新增空Map的属性值映射,用于初始化
visits字段 - 可选:如果不需要严格判断元素是否已存在才写入,可以直接删除
ConditionExpression,因为DynamoDB对String Set执行ADD操作天生幂等,重复添加相同元素不会修改原有集合,也不会报错
修改后的完整代码如下:
request := &dynamodb.UpdateItemInput{ // 可选保留条件,如果需要感知本次操作是否新增了元素的话可以留,否则可以删除 ConditionExpression: aws.String("attribute_not_exists(#customer) OR NOT contains(#visits.#place, :newItem)"), ExpressionAttributeNames: map[string]string{ "#customer": "customer", // 主键字段名 "#visits": "visits", "#place": "location53", }, ExpressionAttributeValues: map[string]dynamotypes.AttributeValue{ ":newItem": &dynamotypes.AttributeValueMemberSS{Value: []string{"item4"}}, // 新增空Map用于初始化visits字段 ":emptyMap": &dynamotypes.AttributeValueMemberM{Value: map[string]dynamotypes.AttributeValue{}}, }, Key: map[string]dynamotypes.AttributeValue{ partitionKeyName: &dynamotypes.AttributeValueMemberS{Value: "some-customer-id-here"}, }, TableName: aws.String("visits"), // 先初始化visits,再执行ADD操作 UpdateExpression: aws.String("SET #visits = if_not_exists(#visits, :emptyMap), ADD #visits.#place :newItem"), } db.UpdateItem(context.Background(), request)
该方案可以覆盖所有需求场景:
- 客户条目不存在:自动创建条目,初始化
visits为空Map后添加location53集合,值为["item4"] - 客户存在但
visits中无location53字段:自动创建location53的String Set,值为["item4"] - 客户存在且
visits中已有location53字段:自动将item4追加到现有集合中(自动去重)
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

