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

如何修改Prisma查询以获取分类、子论坛的主题及帖子数?

解决Prisma查询分类、子论坛主题数与帖子数的问题

问题背景

我有如下Prisma Schema:

model Category {
  id          Int         @id @default(autoincrement())
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt
  title       String
  description String
  deleted     DateTime?
  subforums   Subforum[]
}

model Subforum {
  id          Int         @id @default(autoincrement())
  categoryId  Int
  parentId    Int?
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt
  title       String
  description String
  deleted     DateTime?
  threads     Thread[]
  children    Subforum[]  @relation("ChildSubforums")
  category    Category    @relation(fields: [categoryId], references: [id])
  parent      Subforum?   @relation("ChildSubforums", fields: [parentId], references: [id])
}

model Thread {
  id         Int       @id @default(autoincrement())
  authorId   String
  subforumId Int
  createdAt  DateTime  @default(now())
  updatedAt  DateTime  @updatedAt
  title      String
  content    String
  deleted    DateTime?
  posts      Post[]
  author     User      @relation(fields: [authorId], references: [id])
  subforum   Subforum  @relation(fields: [subforumId], references: [id])
}

model Post {
  id        Int       @id @default(autoincrement())
  authorId  String
  threadId  Int
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  content   String
  deleted   DateTime?
  author    User      @relation(fields: [authorId], references: [id])
  thread    Thread    @relation(fields: [threadId], references: [id])
}

我需要构建如下结构的对象:

interface Subforum {
    id: number;
    title: string;
    threads: number;
    posts: number;
}

interface Category {
    id: number;
    title: string;
    subforums: Subforum[]
}

const categories: Category[] = getCategories();

目前我的getCategories函数能获取分类、子论坛及子论坛的主题数,但无法获取子论坛的帖子数,也不知道如何仅选择分类的指定字段:

export async function getCategories() {
  const categories = await db.category.findMany({
    where: {
      deleted: {
        equals: null,
      },
    },
    include: {
      subforums: {
        select: {
          id: true,
          title: true,
          _count: {
            select: {
              threads: true,
            },
          },
        },
      },
    },
  });

  return categories;
}

请问如何修改getCategories函数(如有需要也可修改schema)以实现目标?


解决方案

1. 修改查询函数,直接获取并转换数据

无需修改Schema,通过Prisma的嵌套统计和字段选择即可实现需求:

export async function getCategories() {
  const rawData = await db.category.findMany({
    where: {
      deleted: null,
    },
    // 仅选择Category需要的字段,避免冗余
    select: {
      id: true,
      title: true,
      subforums: {
        // 可选:过滤已删除的子论坛
        where: { deleted: null },
        select: {
          id: true,
          title: true,
          _count: {
            select: {
              // 统计子论坛的主题数量
              threads: {
                where: { deleted: null },
              },
              // 嵌套统计每个主题下的帖子数
              threads: {
                where: { deleted: null },
                _count: {
                  select: { posts: { where: { deleted: null } } }
                }
              }
            }
          }
        }
      }
    }
  });

  // 将原始数据转换为目标接口结构
  return rawData.map(category => ({
    id: category.id,
    title: category.title,
    subforums: category.subforums.map(subforum => ({
      id: subforum.id,
      title: subforum.title,
      threads: subforum._count.threads.length,
      // 求和所有主题的帖子数得到子论坛总帖子数
      posts: subforum._count.threads.reduce((total, thread) => total + thread.posts, 0)
    }))
  }));
}

2. 可选:添加Schema计算字段(简化查询)

如果希望查询逻辑更简洁,可以给Subforum添加一个忽略数据库存储的计算字段,用于存储帖子总数:

修改Schema:

model Subforum {
  id          Int         @id @default(autoincrement())
  categoryId  Int
  parentId    Int?
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt
  title       String
  description String
  deleted     DateTime?
  threads     Thread[]
  children    Subforum[]  @relation("ChildSubforums")
  category    Category    @relation(fields: [categoryId], references: [id])
  parent      Subforum?   @relation("ChildSubforums", fields: [parentId], references: [id])

  // 新增计算字段,仅用于代码层面,不存储到数据库
  postCount   Int         @ignore
}

之后可以在查询后直接给该字段赋值,不过第一种原生嵌套统计的方式更符合Prisma的使用习惯。

核心说明

  • 指定分类字段:通过select明确选择id和title,只获取需要的数据。
  • 帖子数统计:通过threads._count.posts嵌套统计每个主题的有效帖子数,再求和得到子论坛的总帖子数。
  • 软删除过滤:在where中添加deleted: null,确保返回的都是未删除的有效数据(可根据业务需求调整)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:43:15