#pagination #graphql-ruby
#разбивка на страницы #graphql-ruby
Вопрос:
Представьте, что у вас есть пользователи и подписки на что-то. Вам нужно сделать разбивку на страницы для пользовательских подписок. У каждого пользователя разное количество подписок. Это первое, что пришло мне в голову:
users = User.where(id:[array]).index_by(amp;:id) # find users and make an object with id as a key
subs = Subs.where(user_id: [array]).limit(3).offset(1) # find subs for all users what we need
subs.forEach{|s| users[s[:id]].subs << s} # build graphql response
Но это не сработает, потому что это создает ограничение для всех пользователей в целом, но нам нужно для каждого из них.
Вывод должен быть таким:
{
users: [
{
id: 1,
subs: [sub1, sub2] // this user has only two elements and it's like an end of pagination
},
{
id: 2,
subs: [sub3, sub4, sub5] // this user has more items on next page
}
]
}
Graphql по умолчанию создает подзапросы для каждого пользователя, чтобы сделать его реальным, но это n 1. Есть ли какие-либо способы сделать это без n 1 и оптимизировать использование процессора и памяти?
Ответ №1:
Решаемая здесь https://elixirforum.com/t/how-to-do-pagination-in-a-nested-graphql-query-with-dataloader-batch-load/25282 может быть, это кому-то поможет. Это должен быть запрос, подобный этому, с разделением.
def query(queryable, params) do
case params do
%{chapters: true, offset: offset, first: first} ->
last = offset first
query = from r in queryable, select: r, select_merge: %{chapter_number: fragment("row_number() over (PARTITION by parent_id order by "name")")}
from r in subquery(query), select: %Wikisource.Book{id: r.id, name: r.name, info: r.info, preface: r.preface, info_html: r.info_html, preface_html: r.preface_html}, where: r.chapter_number >= ^offset and r.chapter_number < ^last
%{order_by: order_by, offset: from, first: size} -> from record in queryable, order_by: ^order_by, offset: ^from, limit: ^size