如何修改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
相关产品推荐
相关产品推荐

