与 Ecto 执行联合

Mar*_*van 5 union elixir ecto phoenix-framework

我正在 Phoenix 应用程序中的三个表上运行搜索功能,并且我想使用 SQL 的 UNION 运算符之类的东西来连接它们。

我有三张桌子:

mix phx.gen.json Accounts User users handle:string email:string
mix phx.gen.json Content Post posts title:string content:string
mix phx.gen.json Content Category categories name:string
Run Code Online (Sandbox Code Playgroud)

我们假设没有外键或链接表。

如果我想在 SQL 中对这些进行搜索,我会这样做:

SELECT handle FROM users WHERE handle LIKE "%string%"
UNION
SELECT title FROM posts WHERE title LIKE "%string%"
UNION
SELECT name FROM categories WHERE name LIKE "%string%"
Run Code Online (Sandbox Code Playgroud)

然而,Ecto 2 似乎不支持联合。我想做这样的事情:

query1 =
  from u in User,
    where: ilike(u.handle, ^"%#{str}%"),
    select: u

query2 =
  from p in Post,
    where: ilike(p.title, ^"%#{str}%"),
    select: p

query3 =
  from c in Category,
    where: ilike(c.name, ^"%#{str}%"),
    select: c

union = Ecto.SomethingLikeAUnion([query1, query2, query3])
result = Repo.all(union)
Run Code Online (Sandbox Code Playgroud)

做这个的最好方式是什么?

Dog*_*ert 2

Ecto 目前不支持工会。在 Ecto 添加对联合的支持之前,最好的方法是使用原始 SQL Repo.query/2

MyApp.Repo.query("""
  SELECT handle FROM users WHERE handle LIKE $1
  UNION
  SELECT title FROM posts WHERE title LIKE $1
  UNION
  SELECT name FROM categories WHERE name LIKE $1
""", ["%#{str}%"])
Run Code Online (Sandbox Code Playgroud)