You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Prisma的Post模型查询所有帖子的平均点赞数?

问题原因

你没法直接用aggregate查询平均点赞数,是因为likedBy是多对多关系字段,Prisma的aggregate方法目前仅支持对模型的标量字段(比如你代码里的views这种直接存储在Post表的字段)做聚合运算,不能直接对关系字段的计数做聚合,这也是你在生成的类型提示里找不到对应选项的原因。

解决方案

这里提供两种常用实现方式:

方案1:新增冗余标量字段(生产环境推荐,性能最优)

这是项目中最常用的方案,只需要给Post模型加一个likesCount标量字段存储点赞数即可:

model Post {
  // 原有字段保持不变
  likesCount Int @default(0) // 新增冗余字段,存储当前帖子的点赞总数
  likedBy    UserProfile[]  
}

之后处理点赞/取消点赞逻辑时,同步原子更新这个likesCount字段即可,点赞逻辑示例:

// 点赞操作:同时关联点赞用户、更新点赞数
await prisma.post.update({
  where: { id: postId },
  data: {
    likedBy: { connect: { id: userId } },
    likesCount: { increment: 1 }
  }
})

后续查询平均点赞数的逻辑就和查询平均浏览量完全一致:

let queryAvgLikes = async () => {
  let query = await prisma.post.aggregate({
    _avg: {
      likesCount: true
    }
  })
  return query._avg.likesCount
}

方案2:不修改模型,直接查询计算

如果不想新增冗余字段,也可以先查询所有帖子的点赞数,再手动计算平均值:

let queryAvgLikes = async () => {
  // 先批量查询所有帖子的点赞数
  const postsWithLikeCount = await prisma.post.findMany({
    select: {
      _count: {
        select: { likedBy: true }
      }
    }
  })
  if (postsWithLikeCount.length === 0) return 0
  // 求和后除以帖子总数得到平均值
  const totalLikes = postsWithLikeCount.reduce((sum, post) => sum + post._count.likedBy, 0)
  return totalLikes / postsWithLikeCount.length
}

如果数据量较大,上面的方法会有性能损耗,可以用原始SQL查询提升效率,以PostgreSQL为例:

const result = await prisma.$queryRaw`
  SELECT AVG(like_count) as avg_likes
  FROM (
    SELECT COUNT("likedByUserId") as like_count
    FROM "_PostToUserProfile"
    GROUP BY "postId"
  ) as post_likes
`
return result[0].avg_likes

注意:原始SQL中的多对多中间表名需要和Prisma自动生成的表名保持一致,如果你自定义了多对多中间表,替换为对应的表名即可。

内容的提问来源于stack exchange,提问作者TheHackerCoding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 11:57:02