如何在 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 函数中,您可以添加新的子句来处理不同的键和值。