2017-03-15 14 views
0

アソシエーションのうちの1つ(アライブ)の集計を含むモデル(つまり、ポスト)のすべてを返すクエリを作成することは可能ですか?Ectoでの関連付けが1つであるモデルのクエリを実行できますか?

Repo.all(from p in Post, 
    join: l in Like, 
    where l.post_id == p.id, 
    group_by: p.id, 
    select: {p, count(l.id) 

私はgroup_byを使用して(上記)を選択してみましたが、これは部分的にしか動作しません。クエリの結果は、好き嫌いのある投稿をすべて除外します。

これができない場合は、この問題を処理するにはどうすればよいでしょうか?そのようなのようなクエリの結果の上にマインドマップに来る最初の事:

posts = 
    Repo.all Post 
    |> Enum.map(fn(post) -> 
     likes_query = from l in Like, where: l.post_id == ^post.id 
     likes_count = Repo.aggregate(likes_query, :count, :id) 

     %{post: post, likes_count: likes_count} 
    end) 
+1

参加 '変更してみてください:'へ ' left_join: '最初のスニペットで。 – Dogbert

+1

そして 'where:'を 'on:'に変更してください。 – Dogbert

+0

@Dogbert Nice!それは動作します。 – ocwang

答えて

3

クエリと間違って二つのものがあります。

  1. あなたが指定するonの代わりwhereを使用する必要がありますが、参加条件

  2. 返信不要の投稿を希望される場合は、joinの代わりにleft_joinを使用する必要があります。

最終クエリ:

from p in Post, 
    left_join: l in Like, 
    on: l.post_id == p.id, 
    group_by: p.id, 
    select: {p, count(l.id)} 

ます。また、自動的に正しいonが追加されますされ、ここでleft_joinassocを使用することができます。

from p in Post, 
    left_join: l in assoc(p, :likes), 
    group_by: p.id, 
    select: {p, count(l.id)} 
+0

フォローアップとして、第3の関連付け(コメント)も追加したい場合はどうすればよいですか?私は以下のことを試したが、結果は正しくない 'postのleft_join:l assoc(p、:likes)、left_join:c assoc(p、:コメント)、group_by:p.id、select:{ (l.id)、count(l.id)、count(c.id)} ' – ocwang

+1

私は結合では可能ではないと思っていますが、これにサブクエリを使うことができると思います:https://hexdocs.pm/ecto/Ecto.Query .html#subquery/1 – Dogbert

関連する問題