【问题标题】:Graphql-ruby pagination with limits generates n+1 queries带有限制的 Graphql-ruby 分页生成 n+1 个查询
【发布时间】:2020-09-30 08:45:16
【问题描述】:

想象一下你有用户和订阅的东西。您需要为用户的订阅进行分页。每个用户都有不同数量的订阅。这是我想到的第一件事:

users = User.where(id:[array]).index_by(&: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并通过cpu和内存使用优化?

【问题讨论】:

    标签: pagination graphql-ruby


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 2016-03-27
      • 2018-10-08
      • 2019-05-27
      • 1970-01-01
      相关资源
      最近更新 更多