如何在 Ecto 中写这个 where 子句
how to write this where clause in Ecto
我必须过滤一个在某些情况下可以接受逗号分隔值的索引。我正在与 Ecto 合作,没有凤凰(与牛仔)。
我的索引将支持这样的搜索
/users?ids=1,2,3&email=simple@email.com&another=something
其中 email 字段不允许超过 1 个参数,ids 支持超过 1 个 id
这是我试过的
def list_all(query_params) do
filtered_params = prepare_list_query(query_params)
User
|> where(^filtered_params)
|> Repo.all()
end
# In order to simplify queries I decided to manage all queries as IN clause
# it will returns [id: [1,2,3], email:["something@mymail.com"]]
defp prepare_list_query(query_params) do
query_params
|> Map.take(~w(ids email another))
# Careful: read reference #1 above
|> Enum.map(fn {name, value} ->
case name do
"ids" -> {:id, String.split(value, ",")}
single_param -> {String.to_atom(single_param), [value]}
end
end)
end
这很棘手,但我的想法是 return
[id: [1,2,3], email:["something@mymail.com"]]
然后将所有过滤器用作 IN 子句。
此过滤器必须支持发送零个、一个或所有参数。
我是长生不老药世界的新手,正在迈出我的第一步。
提前致谢:)。
您可以使用Enum.reduce/3
根据参数
动态构建一个ecto查询
def list_all(query_params) do
query = User # initial query
query_params
|> Map.take(~w(ids email another))
|> Enum.reduce(query, fn
{_key, value} when value in [nil, ""], q ->
q # ignore empty values
{"ids", value}, q ->
ids = String.split(values, ",")
q |> where([r], r.id in ^ids)
{key, value} ->
args = [{key, value}]
q |> where(^args)
end
end)
|> Repo.all()
end
在 reduce 函数中,您可以添加新的子句来处理不同的键和值。
我必须过滤一个在某些情况下可以接受逗号分隔值的索引。我正在与 Ecto 合作,没有凤凰(与牛仔)。
我的索引将支持这样的搜索
/users?ids=1,2,3&email=simple@email.com&another=something
其中 email 字段不允许超过 1 个参数,ids 支持超过 1 个 id
这是我试过的
def list_all(query_params) do
filtered_params = prepare_list_query(query_params)
User
|> where(^filtered_params)
|> Repo.all()
end
# In order to simplify queries I decided to manage all queries as IN clause
# it will returns [id: [1,2,3], email:["something@mymail.com"]]
defp prepare_list_query(query_params) do
query_params
|> Map.take(~w(ids email another))
# Careful: read reference #1 above
|> Enum.map(fn {name, value} ->
case name do
"ids" -> {:id, String.split(value, ",")}
single_param -> {String.to_atom(single_param), [value]}
end
end)
end
这很棘手,但我的想法是 return
[id: [1,2,3], email:["something@mymail.com"]]
然后将所有过滤器用作 IN 子句。
此过滤器必须支持发送零个、一个或所有参数。
我是长生不老药世界的新手,正在迈出我的第一步。
提前致谢:)。
您可以使用Enum.reduce/3
根据参数
def list_all(query_params) do
query = User # initial query
query_params
|> Map.take(~w(ids email another))
|> Enum.reduce(query, fn
{_key, value} when value in [nil, ""], q ->
q # ignore empty values
{"ids", value}, q ->
ids = String.split(values, ",")
q |> where([r], r.id in ^ids)
{key, value} ->
args = [{key, value}]
q |> where(^args)
end
end)
|> Repo.all()
end
在 reduce 函数中,您可以添加新的子句来处理不同的键和值。