Elixir + Absinthe + Ecto + Dataloader – 按多个字段过滤
Elixir + Absinthe + Ecto + Dataloader – filter by multiple fields
使用 Elixir/Absinthe/Ecto/Dataloader,如何 query/filter 多个字段的来源?
示例:
假设您希望通过两个字段过滤名为 User
的模式(和数据加载器源),一个名为 is_admin
(仅 true
值)和一个 group_id
可以是列表中的任何值,例如 [1, 5, 9]
使用 Dataloader 会怎样?
这是来自架构定义:
alias App.Data
# ...
object :app do
field :users, list_of(:user) do
resolve fn app, _args, %{context: %{loader: loader}} ->
params = [is_admin: true, group_id: [1,2,3]]
loader
|> Data.load_many(:users, params)
|> on_load(fn loader ->
{:ok, Data.get_many(loader, :user, params)}
end)
end
end
end
这是数据源模块:
defmodule App.Data do
alias App.User
def data do
Dataloader.Ecto.new(Repo, run_batch: &run_batch/5)
end
def load_many(loader, :users, [is_admin: is_admin, group_id: ids]) do
Dataloader.load(loader, __MODULE__, {:many, {User, is_admin: is_admin}}, group_id: ids)
end
def get_many(loader, :users, [is_admin: is_admin, group_id: ids]) do
Dataloader.load(loader, __MODULE__, {:many, {User, is_admin: is_admin}}, group_id: ids)
end
def run_batch(queryable, query, col, inputs, repo_opts) do
Dataloader.Ecto.run_batch(Repo, queryable, query, col, inputs, repo_opts)
end
end
因此,为了回答我自己的问题,有效的解决方案是利用 Dataloader 的 &query/2
,因此 GQL 解析器中的解析器基本上如下所示:
loader
|> Data.load({:many, User, group_ids: ids}, is_admin: true)
|> on_load(fn loader ->
loader
|> Data.get({:many, User, group_ids: ids}, is_admin: true)
# ...
end)
... App.Data
模块中的 query/2
方法如下所示:
defp query(User, %{group_ids: ids}) do
from u in User, where: u.group_id in ^ids
end
这里有解释:
https://hexdocs.pm/lazyloader/Dataloader.Ecto.html#module-filtering-ordering
使用 Elixir/Absinthe/Ecto/Dataloader,如何 query/filter 多个字段的来源?
示例:
假设您希望通过两个字段过滤名为 User
的模式(和数据加载器源),一个名为 is_admin
(仅 true
值)和一个 group_id
可以是列表中的任何值,例如 [1, 5, 9]
使用 Dataloader 会怎样?
这是来自架构定义:
alias App.Data
# ...
object :app do
field :users, list_of(:user) do
resolve fn app, _args, %{context: %{loader: loader}} ->
params = [is_admin: true, group_id: [1,2,3]]
loader
|> Data.load_many(:users, params)
|> on_load(fn loader ->
{:ok, Data.get_many(loader, :user, params)}
end)
end
end
end
这是数据源模块:
defmodule App.Data do
alias App.User
def data do
Dataloader.Ecto.new(Repo, run_batch: &run_batch/5)
end
def load_many(loader, :users, [is_admin: is_admin, group_id: ids]) do
Dataloader.load(loader, __MODULE__, {:many, {User, is_admin: is_admin}}, group_id: ids)
end
def get_many(loader, :users, [is_admin: is_admin, group_id: ids]) do
Dataloader.load(loader, __MODULE__, {:many, {User, is_admin: is_admin}}, group_id: ids)
end
def run_batch(queryable, query, col, inputs, repo_opts) do
Dataloader.Ecto.run_batch(Repo, queryable, query, col, inputs, repo_opts)
end
end
因此,为了回答我自己的问题,有效的解决方案是利用 Dataloader 的 &query/2
,因此 GQL 解析器中的解析器基本上如下所示:
loader
|> Data.load({:many, User, group_ids: ids}, is_admin: true)
|> on_load(fn loader ->
loader
|> Data.get({:many, User, group_ids: ids}, is_admin: true)
# ...
end)
... App.Data
模块中的 query/2
方法如下所示:
defp query(User, %{group_ids: ids}) do
from u in User, where: u.group_id in ^ids
end
这里有解释:
https://hexdocs.pm/lazyloader/Dataloader.Ecto.html#module-filtering-ordering