如何在AWS DynamoDB文档API上更新地图或列表?

新的AWS DynamoDB文档API允许直接对应于底层JSON表示的2种新数据类型:Map(也称为JSON对象)和List(也称为JSON数组)。

但是,我找不到更新这些数据类型的属性而不完全覆盖它们的方法。 相反,可以通过添加另一个数字来更新Number属性,因此在Java中您可以执行以下操作:

new AttributeUpdate("Some numeric attribute").addNumeric(17); 

同样,您可以将元素添加到Set数据类型的属性中。 (在旧的API中,您可以将AttributeAction.ADD用于这两个目的。)

但对于Map或List,似乎必须在本地更新先前的值,然后将其PUT而不是该值,例如在Java中:

 List list = item.getList("Some list attribute"); list.add("new element"); new AttributeUpdate("Some list attribute").put(list); 

这种可读性要低得多,在某些情况下效率低得多。

所以我的问题是:

  1. 有没有办法更新Map或List数据类型的属性而不覆盖以前的值? 例如,要将元素添加到List中,还是将元素放入Map中?

  2. 您将如何使用Java API实现它?

  3. 你知道将来支持这个计划吗?

请查看UpdateItem API中的UpdateExpression

例如,给定一个带有列表的项目:

 { "hashkey": {"S" : "my_key"}, "my_list" : {"L": [{"N":"3"},{"N":"7"} ] } 

您可以使用以下代码更新列表:

 UpdateItemRequest request = new UpdateItemRequest(); request.setTableName("myTableName"); request.setKey(Collections.singletonMap("hashkey", new AttributeValue().withS("my_key"))); request.setUpdateExpression("list_append(:prepend_value, my_list)"); request.setExpressionAttributeValues( Collections.singletonMap(":prepend_value", new AttributeValue().withN("1")) ); dynamodb.updateItem(request);` 

您还可以通过反转list_append表达式中参数的顺序来追加到列表中。

像: SET user.address.zipcode = :zip这样的表达式将解决与表达式属性值{":zip" : {"N":"12345"}}结合的JSON地图元素

基于DynamoDB示例,这也有效(scala)

 val updateItemSpec:UpdateItemSpec = new UpdateItemSpec() .withPrimaryKey("hashkey", my_key) .withUpdateExpression("set my_list = list_append(:prepend_value, my_list)") .withValueMap(new ValueMap() .withList(":prepend_value", "1")) .withReturnValues(ReturnValue.UPDATED_NEW) println("Updating the item...") val outcome: UpdateItemOutcome = table.updateItem(updateItemSpec) println("UpdateItem succeeded:\n" + outcome.getItem.toJSONPretty)