在长生不老药数据加载器中有效解决归属关系



是否可以使用elixir数据加载器高效查询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模式更加丑陋和不友好,因为我需要在这里明确指定父模式的nodeschema和node_id字段,而不是让dataloader从现有的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检查似乎应该发生在子对象上,而不是父对象上。

最新更新