2017-10-13 4 views
0

Je cours une fonction de recherche sur trois tables dans mon application Phoenix, et je veux les rejoindre en utilisant quelque chose comme l'opérateur UNION de SQL.Effectuer des unions avec Ecto

J'ai trois tables:

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 

Supposons qu'il n'y a pas de clés étrangères ou des tables de liaison.

Si je voulais lancer une recherche à travers ces derniers dans SQL, je ferais quelque chose comme ceci:

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%" 

Cependant, Ecto 2 ne semble pas soutenir les syndicats. Je veux faire quelque chose comme ceci:

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) 

Quelle est la meilleure façon de faire cela?

+1

pas ce que vous demandez, mais ... C'est un cas où j'utilise souvent quelque chose comme Elasticsearch. Il fait un bien meilleur travail de recherche et l'UNION serait un non-problème. Totalement compréhensible si vous hésitez à ajouter une technologie supplémentaire à votre application, cependant. – cleaver

Répondre

1

Ecto doesn't support unions at the moment. Jusqu'à ce que Ecto ajoute le support pour les syndicats, la meilleure façon serait d'utiliser SQL brut avec 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}%"])