Нумерация страниц Graphql-ruby с ограничениями генерирует n 1 запросов

#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