Пагинация на основе числовых ограничений и смещений в DynamoDB (Java)

Я хочу реализовать разбиение на страницы на основе числового ограничения и смещения в DynamoDB аналогично Postgres.

Мой API выглядит примерно так: http://foo.bar/user?offset=50&limit=20.

Как лучше всего сделать это на Java, не рискуя OutOfMemoryError, учитывая DynamoDB использует ExclusiveStartKey и LastEvaluatedKey для разбивки на страницы?

РЕДАКТИРОВАТЬ:

Предположим, что разбивка на страницы на основе смещения является жестким требованием, и я не знаю «предыдущую» страницу. В моем контракте API есть параметры запроса offset и limit, как описано выше. Я не ищу ответов "не делать разбиение на страницы на основе смещения".


person gerrytan    schedule 20.09.2019    source источник
comment
Пагинация на основе смещения (0, 20, 40, 60 ...) для 20 записей по сравнению с поиском последнего ключа на предыдущей странице + 21 запись. Последний может быть намного быстрее. (Просто предупреждаю о последней технике умной нумерации страниц)   -  person Joop Eggen    schedule 20.09.2019
comment
Спасибо @ joop-eggen, но давайте предположим, что разбивка на страницы на основе смещения является здесь жестким требованием (я добавлю EDIT, чтобы уточнить).   -  person gerrytan    schedule 20.09.2019
comment
Также @JoopEggen, предположим, я не знаю предыдущую страницу, я не сохраняю это состояние   -  person gerrytan    schedule 20.09.2019
comment
(Это действительно метод преодоления медленного доступа к смещению db, требующий удержания и манипулирования данными. Не то, что нужно вставлять в дизайн кода.)   -  person Joop Eggen    schedule 20.09.2019
comment
А, теперь я понимаю, что вы имеете в виду @JoopEggen, у меня может быть отдельная «таблица переходов», содержащая стартовый ключ для каждого «ведра». Теперь, если мне нужно углубиться в страницу, я могу перейти к ближайшей «корзине» вместо того, чтобы переходить с самого начала. Но для этого мне нужно каким-то образом поддерживать эту таблицу переходов при обновлении исходной таблицы. Это интересная идея. Интересно, есть ли библиотека / шаблон, который может помочь в этом.   -  person gerrytan    schedule 20.09.2019
comment
Это можно делать лениво; Я не знаю, какие библиотеки разбивки на страницы используют его. Встреча с ним здесь (?) Была неожиданностью. Кэш ключей страниц, возможно, уменьшенный до страниц 100, 200, 300, ... или что-то подобное можно вообразить. Я хотел бы найти новый термин для этой техники.   -  person Joop Eggen    schedule 20.09.2019


Ответы (1)


Посмотрев на как PaginatedList работает в sdk, кажется, самый эффективный способ - использовать ITERATION_ONLY стратегию загрузки страниц в конфигурации и сделать что-то вроде этого:

DynamoDBMapperConfig config = new DynamoDBMapperConfig.Builder()
                       .withPaginationLoadingStrategy(ITERATION_ONLY)
                       .build();
PaginatedQueryList<MyUser> users = dynamoDBMapper.query(MyUser.class, myQueryExpression, config);
// This iterator will fetch 1MB worth of data 'on-demand'
Iterator<MyUser> userIterator = users.iterator();
skip(iterator, offset);
List<MyUser> aPageOfUser = collect(iterator, limit);

Конечно, я понесу затраты на реализацию там моих собственных skip и collect методов. Есть ли лучший / более сжатый способ сделать это?

РЕДАКТИРОВАТЬ:

Кажется, я могу использовать IteratorUtils из общих источников -коллекции, чтобы skip и collect бесплатно:

Iterator<MyUser> userIterator = IteratorUtils.boundedIterator(users.iterator(), offset, limit);
List<MyUser> aPageOfUser = IteratorUtils.toList(userIterator);

person gerrytan    schedule 20.09.2019