微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Graphql Ruby N + 1 查询因为方法调用另一个关系

如何解决Graphql Ruby N + 1 查询因为方法调用另一个关系

我正在使用 graphql 和批处理加载器 gems 并遇到此 N+1 查询

我有一个属于某个帐户的日历约会,当我们显示约会时间时,我们会根据该帐户的时区进行显示

def appointment_time
  read_attribute(:appointment_time).in_time_zone(self.account.timezone)
end
calendarappts {
  appointmentTime
}

导致 N+1 查询

POST /graphql
USE eager loading detected
  Calendarappt => [:account]
  Add to your query: .includes([:account])
Call stack
  /....rb:866:in `appointment_time'
  /.../app/controllers/graphql_controller.rb:17:in `execute'

我还有许多其他类似的实例方法创建 N+1 查询的示例,但不确定解决此问题的最佳方法

到目前为止,我刚刚看到了直接克服急切加载关联的方法。我是否需要将每个这样的方法都视为一个关联?

例如,这就是我急切加载帐户本身的方式,当我调用方法时是否也需要做类似的事情?

    field :account,AccountType,null: true,resolve: lambda { |obj,_args,_ctx|
            BatchLoader::GraphQL.for(obj.account_id).batch do |account_ids,loader|
              Account.where(id: account_ids).each { |account| loader.call(account.id,account) }
            end
          }

另外,如果我们做这样的事情,它会调用帐户两次吗?

calendarappts {
  appointmentTime
  account {
    id
    name
  }
}

解决方法

假设您使用 graphql-ruby 来处理您的查询,您应该使用 lookahead 查看需要哪些子字段并相应地准备您的查询。

因此,在您的情况下,在实现 callendarAppts 的方法中,您应该执行以下操作:

field :calendar_appts,...,extras: [:lookahead]
def callendar_appts(lookadead:)
  scope = Model.where(...)
  if(lookahead.selects?(:appointment_time))
     scope = scope.includes([:accounts])
  end
  scope.all
end

(我在这里吐槽它,因为尚未提供实际实现)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?