Комментарии 19
К примеру, представьте, что у вас бесконечный скролл в мобильном приложении, когда по достижении конца текущего "пролистывания" отправляется запрос на получение следующей пачки и контент отрисовывается вниз. В таком случае идём только вперёд, и понятие страниц не нужно
select id from product where id > 10000 limit 100
И
select id from product where id < 10000 limit 100 order by id desc
Не сильно будут различаться по сложности
А если нет порядкового id в таблице?
Мы у себя в компании тоже решили использовать эту пагинацию в GraphQL API на одном из проектов. В целом работает все прекрасно, но есть некоторые специфичные для нас нюансы.
но с точки зрения итогового продукта есть ряд вопросов:
— получается для нагруженного проекта нам надо хранить авоську курсоров и следить за тем кто каким курсором пользуется?
— сколько должен жить курсор чтобы пользователь не нарвался на неожиданное поведение пагинации?
— передавать ссылку становится бессмысленно, можно только говорить вот тебе ссылка и промотай там первые 20 страниц?
Иногда это id, но чаще я видел createdBefore (таймстамп). Клиент просто берет таймстамп последней сущности в списке и запрашивает очередную страницу сущностей
С ссылками да, не передать, но редко вижу чтобы ссылку передавали на список, а не на выбранный айтем
важно! в монго есть бакеты!
А что вы подразумеваете под "страницей"? Абстрактный номер страницы, некий offset? Или конкретное содержимое этой страницы?
Если только первое, то да "курсорная" листалка не справится. Она заточена на свойства контента, а не на способ его деления на страницы.
Если же второе, то всё просто:
http://mysite.com/items/?last_key=abcd
где last_key — значение поля документа (реальное или искусственное), которое участвует в запросе к базе данных в качестве "курсора". Например это может быть дата создания документа и запрос в базу будет примерно такой:
SELECT * FROM table WHERE created > {last_key} ORDER BY created LIMIT 100
Есть много случаев, когда такой вариант ссылки будет предпочтительнее. Т.к. меньше вероятность, что ссылка потеряет актуальность, из-за того что подвезли новый контент и теперь на странице номер 10 (в случае листалки по номерам страниц) уже совсем другое содержимое, а не то которое вы хотели показать.
Это перевод на английский идиомы «те же яйца, только в профиль». :)))
P.S.
Вообще я всё больше и больше убеждаюсь, что самое идеальное API и самая лучшая документация (да ещё с полигоном!) есть только у VK, у других по крайней мере ещё не встречал. Ну у iTunes тоже хорошо продуманное (по сравнению с Last.FM) и как раз заточенное под кэширование, хотя оно и немного урезанное по сравнению с приватным API для оф. приложения.
Реализация примерно такая:
— фильтр запоминается и ему присваивается идентификатор
— делается выборка по пользовательскому фильтру
— в отдельную табличку складываются id строк, можно вместе с порядковым номером в выборке, + идентификатор поискового запроса
— пагинация делается по этой табличке, остальные данные тянутся из основной таблицы
Вокруг этого, конечно, есть ещё куча оптимизаций, но этот способ решает главную проблему — медленную относительную выборку.
Главная проблема такого способа — устаревание поисковой выдачи. Но это общая проблема всех кеширующих ускорялок.
Дизайн пагинации страниц в API