Как обновить карту или список для API документов AWS DynamoDB? - программирование

Как обновить карту или список для API документов AWS DynamoDB?

Новый API AWS DynamoDB document позволяет использовать два новых типа данных, которые непосредственно соответствуют базовому представлению JSON: Map (aka JSON object) и List (aka JSON array).

Однако я не могу найти способ обновлять атрибуты этих типов данных без их полной перезаписи. Напротив, атрибут Number может быть обновлен путем добавления другого номера, поэтому в Java вы можете сделать что-то вроде:

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

Аналогично вы можете addElements присвоить атрибуту типа данных Set. (В старом API вы должны использовать AttributeAction.ADD для обеих целей.)

Но для карты или списка кажется, что вы должны обновить предыдущее значение локально, а затем PUT вместо этого значения, например, в Java:

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

Это гораздо менее читаемо и при некоторых обстоятельствах гораздо менее эффективно.

Итак, мои вопросы:

  • Есть ли способ обновить атрибут типа карты или списка, не перезаписывая предыдущее значение? Например, чтобы добавить элемент в список или поместить элемент на карту?

  • Как вы реализуете его с помощью API Java?

  • Знаете ли вы о планах поддержать это в будущем?

4b9b3361

Ответ 1

Пожалуйста, взгляните на UpdateExpression в API-интерфейс UpdateItem

Например, заданный элемент со списком:

{
    "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 будет обращаться к элементу карты JSON в сочетании с значениями атрибута выражения {":zip" : {"N":"12345"}}

Ответ 2

База на примерах 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)