Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在AWS DynamoDB文档API上更新地图或列表?_Java_Amazon Dynamodb - Fatal编程技术网

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

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实现这两

新版本允许两种新的数据类型直接对应于底层JSON表示:Map(又名JSON对象)和List(又名JSON数组)

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

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(列表);
这是可读性差得多,在某些情况下效率也低得多

因此,我的问题是:

  • 有没有一种方法可以在不覆盖以前的值的情况下更新地图或列表数据类型的属性?例如,要将元素添加到列表中,还是要将元素放入映射中

  • 您将如何使用JavaAPI实现它

  • 你知道将来有什么计划支持这一点吗


  • 请看一下中的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;
    }