elixir - 在 Elixir 中编写 Ecto 查询

标签 elixir phoenix-framework ecto

我从客户端传入的参数列表中创建了一个查询列表:

[
  #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



现在假设你得到一个 MapKeyword 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



进一步阅读:
  • 博文:Composable Queries with Ecto and Joins
  • 截屏视频:Composing Ecto Queries
  • Elixir 论坛:Dynamically composing Ecto Queries
  • 关于elixir - 在 Elixir 中编写 Ecto 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52685873/

    相关文章:

    erlang - 为 erlang 寻找持久的、分布式的工作队列

    elixir - 用 "with"语句重构 case 语句

    phoenix-framework - 如何检查结构是否持久化?

    migration - 尝试使用 ecto elixir 创建迁移时出现 Umbrella 应用程序错误

    elixir - 无法在 Phoenix umbrella 应用程序中加载 Assets

    elixir - Plug.Parser 不读取/解析 JSON 正文

    generics - 如何在 Elixir 中类型指定泛型

    elixir - 从插头内调用插头

    phoenix-framework - Phoenix View 模块不可用

    Elixir Ecto - 未知领域