0

我有以下设置:

class Product < ApplicationRecord
  has_many :variants
end

class Variant < ApplicationRecord
  belongs_to :product
end

Types::QueryType = GraphQL::ObjectType.define do
  connection :products, Types::ProductType.connection_type do
    resolve -> (obj, _, _) do
      Product.all.includes(:variants)
    end
  end
end

Types::ProductType = GraphQL::ObjectType.define do
  connection :variants, Types::VariantType.connection_type do
    resolve -> (obj, _, _) { obj.variants }
  end
end

并运行以下查询:

{
  products {
    edges {
      nodes {
        variants {
          edges {
            node {
              id
            }
          }
        }
      }
    }
  }
}

产生以下 SQL 查询:

  Product Load (2.7ms)  SELECT  "products".* FROM "products" LIMIT $1  [["LIMIT", 25]]
  Variant Load (8.6ms)  SELECT "variants".* FROM "variants" WHERE "variants"."product_id" IN (1, 2, 3)
  Variant Load (19.0ms)  SELECT  "variants".* FROM "variants" WHERE "variants"."product_id" = $1 LIMIT $2  [["product_id", 1], ["LIMIT", 25]]
  Variant Load (13.6ms)  SELECT  "variants".* FROM "variants" WHERE "variants"."product_id" = $1 LIMIT $2  [["product_id", 2], ["LIMIT", 25]]
  Variant Load (2.4ms)  SELECT  "variants".* FROM "variants" WHERE "variants"."product_id" = $1 LIMIT $2  [["product_id", 3], ["LIMIT", 25]]

正如我们在 sql 输出中看到的那样,可以includes工作,但 graphql 不在乎,无论如何都会生成 n+1。这是正常行为吗,我被迫使用像 graphql-batch 这样的解决方案来解决这个问题,或者我的设置有什么不对?据我在互联网上看到的,includes对于这种简单的场景,使用应该就足够了,graphql 应该使用预先加载的数据而不是产生 n+1。我在这里做错什么了吗?

我在 graphql-ruby 1.7.9

4

1 回答 1

0

我刚刚收到关于 graphql-ruby 问题跟踪器的回复:

嘿,我注意到 LIMIT 25 被应用于这些查询。你知道它应用在什么地方吗?如果要使用初始查询的结果,则应删除 LIMIT 子句。(我猜如果你要求 .limit(25),ActiveRecord 不会使用缓存关系。)也许你有一个 default_max_page_size?如果删除它会发生什么?

所以,长话短说,我default_max_page_size从我的架构中删除了配置,它解决了这个问题。

于 2019-02-04T16:15:34.197 回答