是否可以合并两个单独的 ecto 查询?

Is it possible to merge two separate ecto queries?

我想知道是否可以将两个查询组合在一起。

我想创建一个接受 ecto 查询并根据情况修改它的函数。

例如,假设我们有一个 users table 允许输入重复的 usernames 并且用户创建以下查询...

query = from(u in "users", select: u)
select_all_unique_users(query)

我希望 select_all_unique_users 函数接受 query 并添加到它,以便它只选择不同的用户名。

this is only an example, I know that I could create a unique_index on the table to avoid this in reality =D

由于 query 是一个底层结构,我想我可以更新 distinct 键来做到这一点。这似乎可行,但缺点是它似乎不太灵活,如果我想添加更复杂的逻辑,看起来很难实现。

简而言之,我想做的是创建一个接受查询并向其添加更多逻辑的函数...

iex()> query = from(u in "users", select: u)
#Ecto.Query<from u0 in "users", select: u0>

iex()> select_all_unique_users(query)
#Ecto.Query<from u0 in "users", distinct: [asc: u0.username], select: u0>

select_all_unique_users 函数将这样实现:

defmodule TestModule do
  def select_all_unique_users(q) do
    from u in q, distinct: u.username
  end
end

您可以像下面这样使用它:

iex(2)> query = from(u in "users", select: u)
#Ecto.Query<from u in "users", select: u>

iex(3)> distinct = TestModule.select_all_unique_users(query)
#Ecto.Query<from u in "users", distinct: [asc: u.username], select: u>

我将 select_all_unique_users 包装在我为此答案创建的模块中,但您可以将其放在您认为合适的任何模块中。

当然可以!

你可以这样做,假设你有一个像这样的 select_all_unique_users/1 函数:

def select_all_unique_users(query) do
  from(u in query, distinct: u.username)
end

应该可以解决问题。所以,你可以这样做:

# using a defined User schema is preferred over "users". Using
# "users" might cause an error for not being able to sellect all fields
# from table without a schema

iex> q = from(u in User, select: u)
#Ecto.Query<from u in User, select: u>
iex> select_all_unique_users(q)
#Ecto.Query<from u in User, distinct: [asc: u.username], select: u>

Notice that the query from select_all_unique_users/1 doesn't have another select statement. It's because only one select expression is allowed. So, if you wanted to select different attributes on your different queries, you might want to add that in select_all_unique_users/1 or any other functions you may have that base on the from(u in User)