【问题标题】:Batch loading a field in absinthe with dataloader使用数据加载器批量加载苦艾酒中的字段
【发布时间】:2020-11-17 01:09:27
【问题描述】:

我的 Absinthe graphql 架构中有一个对象,如下所示:

object :match do
    field(:id, non_null(:id))
    field(:opponent, non_null(:string))
    @desc "The number of votes that have been cast so far."
    field(:vote_count, non_null(:integer), resolve: &MatchResolver.get_vote_count/2)
    # etc...
end

我正在使用 vote_count 的解析器,它使用父 match 执行 ecto 查询。但是,如果查询匹配列表,这将遇到 n+1 查询问题。目前看起来是这样的:

  def get_vote_count(_root, %{source: %Match{} = match}) do
    count = match |> Ecto.assoc(:votes) |> Repo.aggregate(:count, :id)

    {:ok, count}
  end

我已经在使用 dataloader 批量加载子实体,但在使用 Absinthe 提供的 Absinthe.Resolution.Helpers.dataloader 函数时,我似乎无法让 custom run_batch function 工作。

使用 dataloader/ecto 实现自定义批量查询的推荐方法是什么?谁能举个例子,包括架构定义部分?

【问题讨论】:

    标签: elixir ecto dataloader absinthe


    【解决方案1】:

    假设你已经在某个时候做过这样的事情:

    Dataloader.add_source(Match, Match.data())
    
    

    那么我很确定你想像这样使用 arity /3 的解析器函数:

    def get_vote_count(_, %{source: %Match{} = match}, %{context: %{loader: loader}}) do
      loader
      |> Dataloader.load_many(Match, Match.Vote, [match_id: match.id])
      |> Dataload.run()
      |> Dataload.get_many(Match, Match.Vote, [match_id: match.id])
      |> Enum.count
    end
    
    

    我刚刚完成了 Absinthe/Phoenix 后端的编写,所以它在我的脑海中很新鲜,但实际上我根本没有测试过它。它可能需要一些调整。希望它能让你朝着正确的方向前进。

    【讨论】:

      猜你喜欢
      • 2021-07-08
      • 2020-10-25
      • 2018-12-25
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 2018-01-16
      相关资源
      最近更新 更多