我从客户端传入的参数列表中创建了一个查询列表:
[
#Ecto.Query<from v in Video, where: v.brand == ^"Cocacola">,
#Ecto.Query<from v in Video, where: v.type == ^"can">
]
但是,我需要遍历此列表并编写一个查询,该查询是所有查询的累积。
(下一个查询的输入是当前查询等。)
有人能指出我如何做到这一点的正确方向。这将不胜感激!
我知道我可以一一撰写查询。但是我从客户端获取参数并且有一长串字段(品牌、类型等),并且不想对每个字段进行单独的查询。
最佳答案
除非您打开单个查询结构并检查它们的底层实现,否则既不可能也不建议像这样在 Ecto 中连接查询。相反,您应该尝试将它们分解并使其可组合。
Ecto 使您可以非常轻松地将查询组合在一起:
defmodule VideoQueries do
import Ecto.Query
def with_brand(query, brand) do
where(query, [v], v.brand == ^brand)
end
def with_type(query, type) do
where(query, [v], v.type == ^type)
end
def latest_first(query) do
order_by(query, desc: :inserted_at)
end
end
你可以这样称呼它们:
Video
|> VideoQueries.with_brand("Cocacola")
|> VideoQueries.with_type("can")
|> VideoQueries.latest_first
现在假设你得到一个
Map
或 Keyword List
查询参数如果你想应用它们,你仍然可以通过在运行时迭代键/值来调用它们。您可以构建一个为您执行此操作的过滤器方法:# Assuming args are a Keyword List or a Map with Atom keys
def filter(query, args) do
Enum.reduce(args, query, fn {k, v}, query ->
case k do
:brand -> with_brand(query, v)
:type -> with_type(query, v)
_ -> query
end
end)
end
并且可以动态组合这样的查询:
user_input = %{brand: "Cocacola", type: "can"}
Video
|> VideoQueries.filter(user_input)
|> Repo.all
进一步阅读:
关于elixir - 在 Elixir 中编写 Ecto 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52685873/