Java 如何在AWS DynamoDB文档API上更新地图或列表?
新版本允许两种新的数据类型直接对应于底层JSON表示:Map(又名JSON对象)和List(又名JSON数组) 但是,我无法找到一种方法来更新这些数据类型的属性,而不完全覆盖它们。相反,可以通过添加另一个数字来更新数字属性,因此在Java中可以执行以下操作:Java 如何在AWS DynamoDB文档API上更新地图或列表?,java,amazon-dynamodb,Java,Amazon Dynamodb,新版本允许两种新的数据类型直接对应于底层JSON表示:Map(又名JSON对象)和List(又名JSON数组) 但是,我无法找到一种方法来更新这些数据类型的属性,而不完全覆盖它们。相反,可以通过添加另一个数字来更新数字属性,因此在Java中可以执行以下操作: new AttributeUpdate("Some numeric attribute").addNumeric(17); 类似地,您可以将其添加到集合数据类型的属性。(在旧API中,您将使用AttributeAction.ADD实现这两
new AttributeUpdate("Some numeric attribute").addNumeric(17);
类似地,您可以将其添加到集合数据类型的属性。(在旧API中,您将使用AttributeAction.ADD实现这两个目的。)
但对于映射或列表,似乎必须在本地更新以前的值,然后将其替换为该值,例如在Java中:
List<String> list = item.getList("Some list attribute");
list.add("new element");
new AttributeUpdate("Some list attribute").put(list);
List List=item.getList(“某些列表属性”);
列表。添加(“新元素”);
新属性更新(“某些列表属性”).put(列表);
这是可读性差得多,在某些情况下效率也低得多
因此,我的问题是:
请看一下中的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\u append表达式中参数的顺序来追加到列表中
类似于:
SET user.address.zipcode=:zip的表达式将处理一个JSON映射元素,该元素与表达式属性值组合在一起{:zip:{“N”:“12345”}
基于DynamoDB示例,这同样有效(scala)
用于添加或更新键/值对的通用函数。属性updateColumn
应为map类型
更新tableName
属性名称应作为attributeName
在key:value
对下传递,其中primaryKey=primaryKeyValue
public boolean insertKeyValue(String tableName, String primaryKey, String
primaryKeyValue, String attributeName, String newKey, String newValue) {
//Configuration to connect to DynamoDB
Table table = dynamoDB.getTable(tableName);
boolean insertAppendStatus = false;
try {
//Updates when map is already exist in the table
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey(primaryKey, primaryKeyValue)
.withReturnValues(ReturnValue.ALL_NEW)
.withUpdateExpression("set #columnName." + newKey + " = :columnValue")
.withNameMap(new NameMap().with("#columnName", attributeName))
.withValueMap(new ValueMap().with(":columnValue", newValue))
.withConditionExpression("attribute_exists("+ attributeName +")");
table.updateItem(updateItemSpec);
insertAppendStatus = true;
//Add map column when it's not exist in the table
} catch (ConditionalCheckFailedException e) {
HashMap<String, String> map = new HashMap<>();
map.put(newKey, newValue);
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey(primaryKey,primaryKeyValue)
.withReturnValues(ReturnValue.ALL_NEW)
.withUpdateExpression("set #columnName = :m")
.withNameMap(new NameMap().with("#columnName", attributeName))
.withValueMap(new ValueMap().withMap(":m", map));
table.updateItem(updateItemSpec);
insertAppendStatus = true;
} catch(Exception e) {
e.printStackTrace();
}
return insertAppendStatus;
}
public boolean insertKeyValue(字符串tableName、字符串primaryKey、字符串
primaryKeyValue、字符串attributeName、字符串newKey、字符串newValue){
//连接到DynamoDB的配置
Table Table=dynamoDB.getTable(tableName);
布尔insertAppendStatus=false;
试一试{
//当映射已存在于表中时更新
UpdateItemSpec UpdateItemSpec=新的UpdateItemSpec()
.withPrimaryKey(primaryKey,primaryKeyValue)
.WithReturnValue(ReturnValue.ALL_NEW)
.withUpdateExpression(“设置#columnName.+newKey+”=:columnValue”)
.withNameMap(新的NameMap().with(“#columnName”,attributeName))
.withValueMap(new ValueMap().with(“:columnValue”,newValue))
.withConditionExpression(“属性_存在(“+attributeName+”));
表1.updateItem(updateItemSpec);
insertAppendStatus=true;
//在表中不存在映射列时添加该列
}捕获(条件检查失败异常e){
HashMap=newHashMap();
map.put(newKey,newValue);
UpdateItemSpec UpdateItemSpec=新的UpdateItemSpec()
.withPrimaryKey(primaryKey,primaryKeyValue)
.WithReturnValue(ReturnValue.ALL_NEW)
.withUpdateExpression(“set#columnName=:m”)
.withNameMap(新的NameMap().with(“#columnName”,attributeName))
.withValueMap(新的ValueMap().withMap(“:m”,map));
表1.updateItem(updateItemSpec);
insertAppendStatus=true;
}捕获(例外e){
e、 printStackTrace();
}
返回insertAppendStatus;
}
请详细说明此代码如何回答问题(此答案在“迟交答案”审查队列中)根据Ben Schwartz的回答,我只是想提供另一种解决方法,就像亚马逊的例子一样。这完全不起作用。如果我附加的值本身是一个地图而不是上面例子中的数字,你能帮我想一想吗讨论如何将元素附加到列表的文档;看见
public boolean insertKeyValue(String tableName, String primaryKey, String
primaryKeyValue, String attributeName, String newKey, String newValue) {
//Configuration to connect to DynamoDB
Table table = dynamoDB.getTable(tableName);
boolean insertAppendStatus = false;
try {
//Updates when map is already exist in the table
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey(primaryKey, primaryKeyValue)
.withReturnValues(ReturnValue.ALL_NEW)
.withUpdateExpression("set #columnName." + newKey + " = :columnValue")
.withNameMap(new NameMap().with("#columnName", attributeName))
.withValueMap(new ValueMap().with(":columnValue", newValue))
.withConditionExpression("attribute_exists("+ attributeName +")");
table.updateItem(updateItemSpec);
insertAppendStatus = true;
//Add map column when it's not exist in the table
} catch (ConditionalCheckFailedException e) {
HashMap<String, String> map = new HashMap<>();
map.put(newKey, newValue);
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey(primaryKey,primaryKeyValue)
.withReturnValues(ReturnValue.ALL_NEW)
.withUpdateExpression("set #columnName = :m")
.withNameMap(new NameMap().with("#columnName", attributeName))
.withValueMap(new ValueMap().withMap(":m", map));
table.updateItem(updateItemSpec);
insertAppendStatus = true;
} catch(Exception e) {
e.printStackTrace();
}
return insertAppendStatus;
}