【问题标题】:How do I aggregate a has_many field in Phoenix / Ecto?如何在 Phoenix / Ecto 中聚合 has_many 字段?
【发布时间】:2019-02-07 17:51:49
【问题描述】:

例如说我有关系:

Posts has_many Comments

我正在尝试按照以下方式做一些事情:

Post |> Repo.aggregate(:count, :comments)

但是,Ecto 抱怨 :cmets 是一个虚拟字段,因此它无法计算它。有什么好的方法可以解决这个问题?

【问题讨论】:

    标签: phoenix-framework ecto


    【解决方案1】:

    我假设您想要一组帖子的评论计数。如果您想要所有帖子的评论计数,您可以省略 where 子句。

    post_ids = [1, 2, 3]
    Comment
    |> where([c], c.post_id in ^post_ids)
    |> group_by([c], c.post_id)
    |> select([c], {c.post_id, count("*")})
    |> Repo.all()
    

    这将在给定 post_ids 的情况下按帖子对 cme​​ts 进行分组,并计算每个 cmets 的数量。它将返回一个包含元组的列表,例如像这样

    [
      {1, 10},
      {2, 3},
      {3, 5}
    ]
    

    如果帖子没有 cmets,它将不会在结果集中列出。

    【讨论】:

    • 这似乎是一种迟钝的做法。我不能利用这些在数据库中相关的事实吗?
    • 它的两个查询,一个获取帖子,一个获取评论计数。或者,您可以通过连接第一个和第二个查询并在 Post 结构上填充一个虚拟字段来在一个查询中执行此操作。这几乎就是您在 SQL 中的处理方式。
    【解决方案2】:

    这是我的最终解决方案,link has_many clicks

      def list_links_count do
    
        query = 
          from l in Link,
            join: c in Click, as: :click,
            where: c.link_id == l.id,
            group_by: l.id,
            select: {l, count(l.id)}
    
        query |> Repo.all
    
      end
    

    【讨论】:

      猜你喜欢
      • 2018-05-23
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多