Elixir Ecto:多个连接和 reusable/composable 查询
Elixir Ecto : multiple joins and reusable/composable queries
在 Ecto 中,您可以像这样进行 reusable/composable 查询:
defmodule AModel
#...
def anonymous(q), do: q |> where([am], is_null(am.user_id))
end
end
查看更多示例on this blog post。
但是,我在使用多个连接时遇到问题。
假设我们有一个如下所示的模式:
- A模型属于B模型
- BModel 属于 CModel
- CModel 属于 DModel
本文中提出的解决方案不适用于深度连接:
q = DModel
|> join(:inner, [dm], cm in assoc(dm, :c_models))
|> join(:inner, [_, cm], bm in assoc(cm, :b_models))
|> join(:inner, [_, _, bm], am in assoc(bm, :a_models))
|> AModel.anonymous
查询函数将绑定作为第一个(连接的第二个)参数 table。
它包含以前的连接,遗憾的是连接顺序很紧。
在我们的例子中,anonymous
函数以起始 table 为目标。
但是在查询示例中,AModel 是第 4 个绑定 ...
有什么想法或技术可以摆脱这种顺序依赖性吗?
编辑:
我从博客作者那里得到了答案。
他告诉我,除了 table 中的位置之外,没有其他本地方法可以处理绑定。
他还 this article 强调了这一事实。
但看在上帝的份上,如果顺序很重要,为什么我不能在它上面创建一个将名称与绑定索引相关联的命名映射?
这个问题是不是太过分了:p?
也许创建一些 junction tables?
编辑:我可以看出我可能有点太简洁了。我的意思是说你可以在后端建立联结表,然后查询它们。这样你就不需要担心在你的 Ecto 代码中构建连接。我希望这能让我的回答更清楚一些。
使用命名绑定
为此用例添加了 Ecto 3.0 named bindings。
在 Ecto 中,您可以像这样进行 reusable/composable 查询:
defmodule AModel
#...
def anonymous(q), do: q |> where([am], is_null(am.user_id))
end
end
查看更多示例on this blog post。
但是,我在使用多个连接时遇到问题。
假设我们有一个如下所示的模式:
- A模型属于B模型
- BModel 属于 CModel
- CModel 属于 DModel
本文中提出的解决方案不适用于深度连接:
q = DModel
|> join(:inner, [dm], cm in assoc(dm, :c_models))
|> join(:inner, [_, cm], bm in assoc(cm, :b_models))
|> join(:inner, [_, _, bm], am in assoc(bm, :a_models))
|> AModel.anonymous
查询函数将绑定作为第一个(连接的第二个)参数 table。 它包含以前的连接,遗憾的是连接顺序很紧。
在我们的例子中,anonymous
函数以起始 table 为目标。
但是在查询示例中,AModel 是第 4 个绑定 ...
有什么想法或技术可以摆脱这种顺序依赖性吗?
编辑:
我从博客作者那里得到了答案。 他告诉我,除了 table 中的位置之外,没有其他本地方法可以处理绑定。 他还 this article 强调了这一事实。
但看在上帝的份上,如果顺序很重要,为什么我不能在它上面创建一个将名称与绑定索引相关联的命名映射?
这个问题是不是太过分了:p?
也许创建一些 junction tables?
编辑:我可以看出我可能有点太简洁了。我的意思是说你可以在后端建立联结表,然后查询它们。这样你就不需要担心在你的 Ecto 代码中构建连接。我希望这能让我的回答更清楚一些。
使用命名绑定
为此用例添加了 Ecto 3.0 named bindings。