Разбиение страницы с помощью DynamoDBMapper Java AWS SDK

В документах API dinary dyna db поддерживает разбиение на страницы для операций сканирования и запроса. Ловушка здесь заключается в том, чтобы установить ExclusiveStartIndex текущего запроса на значение LastEvaluatedIndex предыдущего запроса для получения следующей заданной (логической страницы) результатов.

Я пытаюсь реализовать то же самое, но я использую DynamoDBMapper, который, кажется, имеет гораздо больше преимуществ, таких как жесткая связь с моделями данных. Поэтому, если бы я хотел сделать выше, я предполагаю, что я сделаю что-то вроде ниже:

// Mapping of hashkey of the last item in previous query operation
Map<String, AttributeValue> lastHashKey = .. 
DynamoDBQueryExpression expression = new DynamoDBQueryExpression();

...
expression.setExclusiveStartKey();
List<Table> nextPageResults = mapper.query(Table.class, expression);

Надеюсь, мое вышеозначение правильное в разбивке на страницы с использованием DynamoDBMapper. Во-вторых, как я узнаю, что достиг результатов. Из документов, если я использую следующий api:

QueryResult result = dynamoDBClient.query((QueryRequest) request);
boolean isEndOfResults = StringUtils.isEmpty(result.getLastEvaluatedKey());

Возвращаясь к использованию DynamoDBMapper, как я могу узнать, достиг ли я в конце концов результатов.

Ответ 1

У вас есть пара различных вариантов с DynamoDBMapper, в зависимости от того, каким способом вы хотите идти.

В этой части мы понимаем разницу между методами и функциональность, которую их возвращаемые объекты инкапсулируют.

Я перейду PaginatedScanList и ScanResultPage, но эти методы/объекты в основном отражают друг друга.

PaginatedScanList говорит следующее, основное внимание:

Реализация интерфейса List, представляющего результаты сканирования в AWS DynamoDB. Потребительские результаты загружаются по требованию, когда пользователь выполняет требуемую им операцию. Некоторые операции, такие как size(), должны извлекать весь список, но при этом результаты становятся лениво выбраны по страницам.

Это говорит о том, что результаты загружаются по мере повторения списка. Когда вы проходите первую страницу, вторая страница автоматически извлекается из-за необходимости явно делать другой запрос. Ложная загрузка результатов является методом по умолчанию, но ее можно переопределить, если вы вызываете перегруженные методы и поставляете DynamoDBMapperConfig с другим DynamoDBMapperConfig.PaginationLoadingStrategy.

Это отличается от ScanResultPage. Вам дается страница результатов, и вы должны сами справиться с разбиением на страницы.

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

final DynamoDBMapper mapper = new DynamoDBMapper(client);

// Using 'PaginatedScanList'
final DynamoDBScanExpression paginatedScanListExpression = new DynamoDBScanExpression()
        .withLimit(limit);
final PaginatedScanList<MyClass> paginatedList = mapper.scan(MyClass.class, paginatedScanListExpression);
paginatedList.forEach(System.out::println);

System.out.println();
// using 'ScanResultPage'
final DynamoDBScanExpression scanPageExpression = new DynamoDBScanExpression()
        .withLimit(limit);
do {
    ScanResultPage<MyClass> scanPage = mapper.scanPage(MyClass.class, scanPageExpression);
    scanPage.getResults().forEach(System.out::println);
    System.out.println("LastEvaluatedKey=" + scanPage.getLastEvaluatedKey());
    scanPageExpression.setExclusiveStartKey(scanPage.getLastEvaluatedKey());

} while (scanPageExpression.getExclusiveStartKey() != null);

И вывод:

MyClass{hash=2}
MyClass{hash=1}
MyClass{hash=3}
MyClass{hash=0}
MyClass{hash=4}

MyClass{hash=2}
MyClass{hash=1}
LastEvaluatedKey={hash={N: 1,}}
MyClass{hash=3}
MyClass{hash=0}
LastEvaluatedKey={hash={N: 0,}}
MyClass{hash=4}
LastEvaluatedKey=null