Size: a a a

GraphQL — русскоговорящее сообщество

2020 January 12

V

Vladlen (Negezor) in GraphQL — русскоговорящее сообщество
egoarka
OFFSET еще есть вроде в sql

LIMIT 10 OFFSET 10
Я же описал это как базовый курсор, а я говорил про второй тип курсора.
источник

e

egoarka in GraphQL — русскоговорящее сообщество
ну ты в sql можешь добавить айди последнего айтема, в чем проблема
источник

e

egoarka in GraphQL — русскоговорящее сообщество
и сам курсор будет состоять из айди последнего айтема по сортировке + оффсет
источник

V

Vladlen (Negezor) in GraphQL — русскоговорящее сообщество
Я же ещё раз говорю, меня интересует именно решение проблемы курсора второго типа основанного на ключах
источник

V

Vladlen (Negezor) in GraphQL — русскоговорящее сообщество
Т.е. без OFFSET
источник

e

egoarka in GraphQL — русскоговорящее сообщество
Vladlen (Negezor)
WHERE id > :afterId ODER BY score DESC
сюда пробовал добавлять свой ключ?)
источник

e

egoarka in GraphQL — русскоговорящее сообщество
если дубликатов нет то должно работать
источник

V

Vladlen (Negezor) in GraphQL — русскоговорящее сообщество
В качестве ID у меня Snowflake. Ключом является ID. Запросы идут как:
WHERE id > :afterId LIMIT :first
источник

V

Vladlen (Negezor) in GraphQL — русскоговорящее сообщество
Но теперь когда мне нужна сортировка допустим по полю score в обратном порядке — данные ключей будут перемешаны
источник

e

egoarka in GraphQL — русскоговорящее сообщество
будут и ничего с этим не поделаешь
хотя я скорее ошибаюсь, может и можно, в курсор можно запихивать что угодно
источник

e

egoarka in GraphQL — русскоговорящее сообщество
Vladlen (Negezor)
Но теперь когда мне нужна сортировка допустим по полю score в обратном порядке — данные ключей будут перемешаны
не будт перемешены по идее, они же в обратном порядке будут, ключи
источник

e

egoarka in GraphQL — русскоговорящее сообщество
Vladlen (Negezor)
А как это поможет?
id | score
1 | 3
2 | 5
3 | 1

В итоге будет порядок:
2 | 5
1 | 3
3 | 1
2 | 5
1 | 3
3 | 1

3 | 1
1 | 3
2 | 5

не вижу различий
источник

V

Vladlen (Negezor) in GraphQL — русскоговорящее сообщество
Vladlen (Negezor)
А как это поможет?
id | score
1 | 3
2 | 5
3 | 1

В итоге будет порядок:
2 | 5
1 | 3
3 | 1
Ну я привёл пример, если у нас будет
id > 2 (он первый в списке)
Мы не увидим запись с ID 1
источник

e

egoarka in GraphQL — русскоговорящее сообщество
ну значит сначала по score сортируй потом по ключу (в одном sql запросе)

чтобы у тебя там и там порядок был
источник

V

Vladlen (Negezor) in GraphQL — русскоговорящее сообщество
Но в итоге получу сортировку по ID)
источник

e

egoarka in GraphQL — русскоговорящее сообщество
в итоге да)
источник

e

egoarka in GraphQL — русскоговорящее сообщество
тут gql так то не причем
источник

e

egoarka in GraphQL — русскоговорящее сообщество
тебе надо хотя бы на sql подумать как ты хочешь
источник

e

egoarka in GraphQL — русскоговорящее сообщество
источник
2020 January 13

P@

Pavel @nodkz in GraphQL — русскоговорящее сообщество
Vladlen (Negezor)
Доброго времени суток! Долгое время я задумывался над решением пагинации через курсоры.

Базовое решение основано на LIMIT/OFFSET.
Плюсы:
- Можно указывать сторону сортировку (DESC/ASC) на конкретную колонку.
Минусы:
- Данные при смещении могут повторяться

Реализация на Primary Key/Timestamp
Плюсы:
- Объекты не будут повторятся
- Курсор остаётся актуальным длительное время

Минусы:
- Невозможно использовать сортировку по колонке не являющиеся ключом (PK/Timestamp)

Конечно понимаю что второй вариант используют в основном в какой-нибудь ленте или списке сообщений. Мне второй вариант нравится больше, но минус перекрывает плюсы.

Так какой будет эталонный вариант реализации будет? Может я чего не учёл.
Релеевские курсоры - хорошая спека: https://facebook.github.io/relay/graphql/connections.htm . Реализовать можно сортировку по любьым УНИКАЛЬНЫМ полю/полям.

Тут чутка инфы, почему нужны уникальные поля для курсора
https://github.com/graphql-compose/graphql-compose-connection/issues/33 В этой же репко можно посмотреть реализацию этой спеки.

Суть работы:
- вы сортируете свой коннекш по какому-то уникальному полю или набору уникальных полей. К примеру захотели сортировать по дате создания и айдишнику (кардиналить даты создания тупо не хватает, т.к. может быть создано много записей в одну секунду. Поэтому еще к дате надо приклеить ID, чтоб реально получать уникальные курсоры): sort: CREATED_AT_AND_ID_DESC
- далее когда возвращаете результаты, для каждой записи в курсор вы должны положить значения согласно той сортировки, которую использовалась в запросе(в моем примере `base64({ createAt: ‘2020-01-12 10:03:15’, id: 1745 })`)
- когда вы хотите получить следующую порцию данных в коннекшене, вы графкуэль запросе должны передать КУРСОР и ту же СОРТИРОВКУ: cursor: base64({ createAt: ‘2020-01-12 10:03:15’, id: 1745 }), sort: CREATED_AT_AND_ID_DESC
- на стороне сервера когда поймали курсок должны правильно сконструировать запрос в базу согласно КУРСОРА и СОРТИРОВКИ, в моем случае WHERE createdAt <= ‘2020-01-12 10:03:15’ AND id < 1745 ORDER BY createdAt DESC, id DESC
источник