Prisma自关联多对多表如何查询所有层级符合条件的嵌套子级?
解决方案
你当前的问题核心有两点:一是子节点查询没有加enabled=true过滤条件,二是默认只能查两级数据,无法获取孙节点及更深层级的内容。以下是两种可直接落地的实现方案:
方案1:固定层级嵌套查询
如果业务中节点层级是固定的(比如最多3级:父/子/孙),可以直接在include里嵌套指定层级的关联查询,同时叠加过滤条件:
import { PrismaClient, Prisma } from '@prisma/client' const prisma = new PrismaClient() export default async function handler(req, res) { const ret = await prisma.antecedant.findMany({ where: { enabled: true, parent_id: null }, include: { children: { where: { enabled: true }, include: { children: { where: { enabled: true } // 如果有更深层级,按规则继续嵌套include即可 } } } } }); res.status(200).json(ret) }
该方案写法简单,缺点是仅适配固定层级场景,层级越深写法越冗余,数据库查询开销也会同步升高。
方案2:全量查询后动态组装树(推荐)
如果节点层级不固定,推荐先一次性查出所有enabled=true的节点,再通过内存计算组装成树形结构,仅需1次数据库查询,性能更高且适配任意层级:
import { PrismaClient, Prisma } from '@prisma/client' const prisma = new PrismaClient() // 树形结构组装工具函数 const buildTree = (nodes) => { const nodeMap = new Map(); const rootNodes = []; // 所有节点存入Map,方便快速索引 nodes.forEach(node => { node.children = []; nodeMap.set(node.id, node); }); // 遍历节点挂载到对应父节点下 nodes.forEach(node => { if (node.parent_id === null) { rootNodes.push(node); } else { const parentNode = nodeMap.get(node.parent_id); if (parentNode) parentNode.children.push(node); } }); return rootNodes; } export default async function handler(req, res) { // 一次性查询所有启用的节点 const allEnabledNodes = await prisma.antecedant.findMany({ where: { enabled: true } }); // 组装成目标树形结构直接返回 const treeData = buildTree(allEnabledNodes); res.status(200).json(treeData) }
内容的提问来源于stack exchange,提问作者Matthieu Raynaud de Fitte
相关产品推荐
相关产品推荐

