我可以在Ecto中查询其中一个关联的聚合计数的模型吗?

时间:2017-03-15 05:10:52

标签: elixir phoenix-framework ecto

是否可以撰写一个返回所有模型(即Post)的查询,其总计数为其中一个关联(即Like)。

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 个答案:

答案 0 :(得分:5)

查询有两个问题:

  1. 您需要使用on代替where来指定加入条件

  2. 如果您希望不返回喜欢的帖子,则需要使用left_join代替join

  3. 最终查询:

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

    您也可以在assoc left_join使用on,这会自动添加正确的from p in Post, left_join: l in assoc(p, :likes), group_by: p.id, select: {p, count(l.id)}

    using Microsoft.ApplicationInsights.Channel;
    using Microsoft.ApplicationInsights.Extensibility;
    
    public class SuccessfulDependencyFilter : ITelemetryProcessor
    {
        private ITelemetryProcessor Next { get; set; }
    
        // Link processors to each other in a chain.
        public SuccessfulDependencyFilter(ITelemetryProcessor next)
        {
            this.Next = next;
        }
    
        public void Process(ITelemetry item)
        {
            if (!OKtoSend(item)) { return; }
    
            this.Next.Process(item);
        }
    
        private bool OKtoSend (ITelemetry item)
        {
            var request = item as RequestTelemetry;
    
            if (request.Name.StartsWith("OPTIONS"))
               return false;
    
            return true;
        }
    }