有效解决 elixir 数据加载器中的 belongs_to 关系?
Efficiently resolving belongs_to relationship in elixir dataloader?
是否可以使用 elixir dataloader 高效地查询 belongs_to
关系?似乎 load
正在查询它需要的所有项目,但是 get
正在返回加载项目的第一个值,而不管它实际需要哪个项目。这是我现在使用的代码:
field :node, :node_object, resolve: fn parent, _, %{context: %{loader: loader}} ->
# parent.node_id = 1, but concurrently also another parent.node_id = 5
loader
|> Dataloader.load(NodeContext, :node, parent) # loads node_id 5 and 1
|> on_load(fn loader ->
loader
|> Dataloader.get(NodeContext, :node, parent) # always returns the node with id = 5
|> (&{:ok, &1}).()
end)
end
我目前的解决方法是使用以下代码,但它使代码更加丑陋并且对 Ecto 模式不友好,因为我需要在此处明确指定节点模式和父模式的 node_id 字段而不是让数据加载器从现有的 ecto 模式中推断它:
field :node, :node_object, resolve: fn parent, _, %{context: %{loader: loader}} ->
loader
|> Dataloader.load(NodeContext, {:one, NodeSchema}, id: parent.node_id)
|> on_load(fn loader ->
loader
|> Dataloader.get(NodeContext, {:one, NodeSchema}, id: parent.node_id)
|> (&{:ok, &1}).()
end)
end
我能够通过像这样将父架构的 node_id
设为 primary_key
来解决此问题:
defmodule MyApp.ParentSchema do
use Ecto.Schema
alias MyApp.NodeSchema
@primary_key false
embedded_schema do
belongs_to :node, NodeSchema, primary_key: true
end
end
我不确定这是否是 dataloader
的预期行为,因为 primary_key
检查似乎应该发生在子对象而不是父对象上。
是否可以使用 elixir dataloader 高效地查询 belongs_to
关系?似乎 load
正在查询它需要的所有项目,但是 get
正在返回加载项目的第一个值,而不管它实际需要哪个项目。这是我现在使用的代码:
field :node, :node_object, resolve: fn parent, _, %{context: %{loader: loader}} ->
# parent.node_id = 1, but concurrently also another parent.node_id = 5
loader
|> Dataloader.load(NodeContext, :node, parent) # loads node_id 5 and 1
|> on_load(fn loader ->
loader
|> Dataloader.get(NodeContext, :node, parent) # always returns the node with id = 5
|> (&{:ok, &1}).()
end)
end
我目前的解决方法是使用以下代码,但它使代码更加丑陋并且对 Ecto 模式不友好,因为我需要在此处明确指定节点模式和父模式的 node_id 字段而不是让数据加载器从现有的 ecto 模式中推断它:
field :node, :node_object, resolve: fn parent, _, %{context: %{loader: loader}} ->
loader
|> Dataloader.load(NodeContext, {:one, NodeSchema}, id: parent.node_id)
|> on_load(fn loader ->
loader
|> Dataloader.get(NodeContext, {:one, NodeSchema}, id: parent.node_id)
|> (&{:ok, &1}).()
end)
end
我能够通过像这样将父架构的 node_id
设为 primary_key
来解决此问题:
defmodule MyApp.ParentSchema do
use Ecto.Schema
alias MyApp.NodeSchema
@primary_key false
embedded_schema do
belongs_to :node, NodeSchema, primary_key: true
end
end
我不确定这是否是 dataloader
的预期行为,因为 primary_key
检查似乎应该发生在子对象而不是父对象上。