Сканирование диапазона AWS DynamoDB с помощью DynamoDBMapper

Я попробовал свою первую попытку использовать DynamoDB после долгого использования реляционных баз данных, теперь это делается для обновления результатов тестирования для последующего анализа, рассмотрите следующую таблицу и вторичный индекс

12

Я пытался получить для данного testName, тест выполняется в известном диапазоне ревизий, используя следующий код Java:

HashMap<String, Condition> scanMap = new HashMap<>();
scanMap.put("revision", new Condition().withComparisonOperator(ComparisonOperator.BETWEEN).withAttributeValueList(Arrays.asList(new AttributeValue("N:"+String.valueOf(minRev)), new AttributeValue("N:"+String.valueOf(maxRev)))));
scanMap.put("testName", new Condition().withComparisonOperator(ComparisonOperator.EQ).withAttributeValueList(new AttributeValue(Collections.singletonList(testName))));
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression().withScanFilter(scanMap);
scanExpression.setIndexName("testName-revision-index");
List<ValidationReport> reports = getMapper().scan(ValidationReport.class, scanExpression);

Я пытался удалить "N:" без везения. Полное удаление выражения ревизии возвращает все тестовые прогоны без ограничения диапазона ревизий.

Любая помощь будет оценена здесь


person Ohad Benita    schedule 24.05.2017    source источник


Ответы (1)


Итак, похоже, что я лаял не на то дерево, пытаясь использовать Scan вместо Query :

Клиент не должен использовать ScanFilter, который устарел. Типы данных List/Map лучше подходят для нового синтаксиса FilterExpression. Я подозреваю, что проблема связана с многозначным атрибутом с «N:» в имени; это не похоже на проводной формат. Чтобы использовать «новые» выражения фильтра, они должны создать ExpressionAttributeNames и ExpressionAttributeValues, чтобы сообщить AWS SDK об атрибутах фильтра, addExpressionAttributeNamesEntry и addExpressionAttributeValuesEntry.http://docs.aws.amazon.com/AWSJavaSDK/last/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBScanExpression.html Кроме того, было бы упущением не указать, что сканирование — абсолютно неподходящее действие API для этого запроса; Запрос - правильное действие. testName следует использовать с Query с KeyConditionExpression, чтобы сузить поиск до нужного раздела, а ревизию следует добавить к тому же с помощью синтаксиса BETWEEN. Сканирование предназначено для резервного копирования и фоновых операций, и в этом случае схема индекса клиента может использоваться с запросом, чтобы сузить поиск. Предупредите их об использовании сканирования; это фундаментальная передовая практика:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScanGuidelines.html

Поэтому вместо этого я использовал Query:

    Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
    eav.put(":v1", new AttributeValue().withS(testName));
    eav.put(":v2", new AttributeValue().withS(version));
    eav.put(":v3", new AttributeValue().withN(String.valueOf(minRev)));
    eav.put(":v4", new AttributeValue().withN(String.valueOf(maxRev)));

    final DynamoDBQueryExpression<ValidationReport> query = new DynamoDBQueryExpression<>();
    query.withKeyConditionExpression("testName = :v1");
    query.withFilterExpression("buildVersion = :v2 and revision BETWEEN :v3 AND :v4");
    query.setConsistentRead(false);
    query.withExpressionAttributeValues(eav);
    return getMapper().query(ValidationReport.class, query);`

Обратите внимание, что при использовании AttributeValue существует большая разница между следующим:

new AttributeValue().withS("SomeStringValue")
new AttributeValue().withN("SomeNumber")

Чего мне не хватало

person Ohad Benita    schedule 25.05.2017