elixir - 使用数据加载器批量加载苦艾酒中的字段
问题描述
我的 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
它使用 parent 执行 ecto 查询match
。但是,如果查询匹配列表,这将遇到 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 提供的函数时,我似乎无法让自定义run_batch
函数工作。Absinthe.Resolution.Helpers.dataloader
使用 dataloader/ecto 实现自定义批量查询的推荐方法是什么?有人可以举个例子,包括架构定义部分吗?
解决方案
假设你已经在某个时候做了这样的事情:
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 后端的编写,所以它在我的脑海中很新鲜,但实际上我根本没有测试过它。它可能需要一些调整。希望它能让你朝着正确的方向前进。
推荐阅读
- java - 如何使用 Android Studio 在 Android 10 中将文件写入外部存储
- reactjs - React Props 不会更新状态
- javascript - 使用 AES-128-ECB 方法在 Java 中加密并在 PHP 中解密
- javascript - 尝试在浏览器中的 html 文件中加载 functions.js 文件时出现 GET 404 错误(*使用节点 js 作为服务器)
- swift - App中同种语言的冗余外观
- java - 删除每页第一行的 FixedLeading
- javascript - 其他内容 CSS 之上的导航栏
- sql - 如何在 Oracle 11g 监听器中启用 SSL
- php - 如何有效地制作许多(100 多个)具有细微差异的 HTML 页面
- java - 编译失败:-source 7 中不支持 lambda 表达式