连接中断包括

时间:2019-02-03 19:09:34

标签: ruby-on-rails ruby rails-activerecord graphql-ruby

我有以下设置:

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

1 个答案:

答案 0 :(得分:0)

我刚刚在graphql-ruby问题跟踪器上收到了a reply

  

嘿,我注意到LIMIT 25正在应用于这些查询。你呢   知道在哪里应用?如果要使用来自的结果   在初始查询中,您应该删除LIMIT子句。 (我正在猜测   如果您要求.limit(25),则ActiveRecord将不会使用缓存的   关系。)也许您有一个default_max_page_size?如果你会发生什么   删除吗?

长话短说,我从架构中删除了 CompositeTransform TextDrag = new CompositeTransform(); CompositeTransform savedTransform = new CompositeTransform(); public MainPage() { this.InitializeComponent(); TextBlock1.RenderTransform = TextDrag; } // Copy Transform X and Y if TextBlock is within bounds private void CopyTransform(CompositeTransform orig, CompositeTransform copy) { copy.TranslateX = orig.TranslateX; copy.TranslateY = orig.TranslateY; } private void TextBlock1_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) { TextDrag.TranslateX += e.Delta.Translation.X; TextDrag.TranslateY += e.Delta.Translation.Y; CompositeTransform transform = TextBlock1.RenderTransform as CompositeTransform; // Get current Top-Left coordinates of TextBlock var TextTopLeft = TextBlock1.TransformToVisual(GridBounds).TransformPoint(new Point(0, 0)); // Get current Bottom-Right coordinates of TextBlock var TextBottomRight = TextBlock1.TransformToVisual(GridBounds).TransformPoint(new Point(TextBlock1.ActualWidth, TextBlock1.ActualHeight)); // Get Top-Left grid coordinates var GridTopLeft = (new Point(0, 0)); // Get Bottom-Right grid coordinates var GridBottomRight = (new Point(GridBounds.ActualWidth, GridBounds.ActualHeight)); if (TextTopLeft.X < GridTopLeft.X || TextBottomRight.X > GridBottomRight.X) { // Out of bounds on X axis - Revert to copied X transform TextDrag.TranslateX = savedTransform.TranslateX; ; } else if (TextTopLeft.Y < GridTopLeft.Y || TextBottomRight.Y > GridBottomRight.Y) { // Out of bounds on Y axis - Revert to copied Y transform TextDrag.TranslateY = savedTransform.TranslateY; } else { // TextBlock is within bounds - Copy X and Y Transform CopyTransform(transform, savedTransform); } } 配置,并解决了该问题。