Выражение обновления AWS Java SDK DynamoDB для «сложного» элемента

#java #amazon-web-services #amazon-dynamodb

Вопрос:

Итак, у меня есть следующий пункт, где TestIDэто ключ сортировки:

 {
 "userId": "admin",
 "testId": "1234",
 "picture": "abstract",
 "numOfUsers": 1,
 "Tests": [
  {
   "duration": 1234,
   "typeId": "2345",
   "interval": 450000,
   "quantity": 333333
  },
  {
   "duration": 1234,
   "typeId": "6789",
   "interval": 450000,
   "quantity": 333333
  },
  {
   "duration": 1234,
   "typeId": "2020",
   "interval": 450000,
   "quantity": 333333
  }
 ]
}
 

Как вы можете видеть, в процессе тестирования находится несколько идентичных предметов. Мой вопрос в том, как мне обновить их все с одинаковым значением? Я имею в виду, что, например, я хотел бы обновить продолжительность для всех трех объектов с 1234 по 2222 год.

Вот код, который я протестировал:

     Table table = dynamoDB.getTable(tableName);
    Map<String, String> expressionAttributeNames = new HashMap<String, String>();
    expressionAttributeNames.put("#A", "Duration");

    Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
    expressionAttributeValues.put(":val1", "2222");

    UpdateItemOutcome outcome =  table.updateItem(
            "testId",         
             "1234",           
            "set #A :val1", 
            expressionAttributeNames,
            expressionAttributeValues);
 

Любая помощь будет признательна 🙂

Комментарии:

1. 1. testId ваш ключ сортировки — каков ваш ключ раздела? 2. несколько одинаковых тестируемых предметов — идентичных с точки зрения чего? продолжительность? 3. должно ли это быть универсальным ака. изменить всех дураков (по продолжительности, я полагаю)? будете ли вы знать имена обманутых заранее? если нет, вам нужно будет сначала получить товар, чтобы затем проверить его на наличие дураков; нам нужна дополнительная информация, пожалуйста 🙂

2. Мой ключ раздела-идентификатор пользователя, и он в основном идентичен для всех элементов. Я имею в виду идентичные ключи, все они имеют одинаковую продолжительность, тип, интервал и количество. Под двойниками вы подразумеваете дублирование? Да, длительность (ключ, значение которого я хотел бы обновить) всегда одинакова для всех трех объектов в разделе «тесты». Я всегда могу получить элемент в формате json, а затем обновить его, используя путь Джейсона, но должен быть элегантный способ сделать это с помощью Table.updateItem

3. если это ваше намерение, вы можете рассмотреть другую стратегию динамовцев. Возможно, PK имени теста, SK даты тестов (если вы запускаете тест более одного раза в день, или какое-либо другое значение, которое приведет к объединению множества тестов, по которым вы могли бы выполнять поиск), а затем каждый атрибут является атрибутом типа карты с именем атрибута идентификатора теста, содержащим json теста.

Ответ №1:

Основываясь на моем понимании DynamoDB и выражений, вам нужно сказать dynamodb, чтобы он углубился в нужный вам атрибут.

Ваш код указывает ему на продолжительность обновления…но где же Продолжительность? Это не на верхнем уровне элемента.

Посмотрим, сработает ли это:

 Table table = dynamoDB.getTable(tableName);
    Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#Dur", "duration");
expressionAttributeNames.put("#Test", "Tests");


Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", "2222");

UpdateItemOutcome outcome =  table.updateItem(
        "testId",         
         "1234",           
        "set #Test.#Dur :val1", 
        expressionAttributeNames,
        expressionAttributeValues);
 

=== Отредактировано ===

 ValueMap valueMap = new ValueMap().withNumber(":dur", 2222));

UpdateItemSpec updateItemSpec = new UpdateItemSpec()
      .withPrimaryKey("key", year)
      .withUpdateExpression("set Tests.duration = :dur")
      .withValueMap(valueMap)
      .withReturnValues(ReturnValue.UPDATED_NEW);

UpdateItemOutcome updateItemOutcome = table.updateItem(updateItemSpec);
 

=== Отредактировано ====

 UpdateItemSpec updateItemSpec = new UpdateItemSpec()
    .withPrimaryKey("key", "primaryKey")
    .withUpdateExpression("set Tests.#duration = :value")
    .withNameMap(new NameMap().with("#duration", "duration"))
    .withValueMap(new ValueMap().withNumber(":value", 2222))
    .withReturnValues(ReturnValue.UPDATED_NEW);
 

Комментарии:

1. Я пытался, но получаю следующее исключение: com.amazonaws.services.dynamodbv2.модель. Исключение AmazonDynamoDBException: Недопустимое выражение обновления: Синтаксическая ошибка; токен: «:val1», рядом: «#Dur :val1» (Служба: AmazonDynamoDBv2; Код состояния: 400; Код ошибки: Исключение проверки; Идентификатор запроса: 4H22J173OT44A8VDVMSQA80CQBVV4KQNSO5AEMVJF66Q9ASUAAJG; Прокси: null)

2. можете ли вы попробовать отредактировать @PloniStacker

3. Спасибо, теперь получаем — com.amazonaws.services.dynamodbv2.модель. Исключение AmazonDynamoDBException: Недопустимое выражение обновления: Имя атрибута является зарезервированным ключевым словом; зарезервированное ключевое слово: длительность (Служба: AmazonDynamoDBv2; Код состояния: 400; Код ошибки: Исключение проверки; Идентификатор запроса: 2HNL4I4NGEEOO1EC4OLNIGDQRRVV4KQNSO5AEMVJF66Q9ASUAAJG; Прокси: null)

4. Давайте попробуем последнее редактирование @PloniStacker 🙂