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

如何在TypeORM中关联查询树形实体并返回findTrees样式的嵌套结果

解决方案

方案1:使用TypeORM内置TreeRepository查询(推荐)

你使用的是物化路径(materialized-path)类型的树形实体,TypeORM自带的TreeRepository原生支持树形结构查询,返回结果直接符合你要的嵌套格式,无需手动处理层级:

import { getTreeRepository } from 'typeorm';
import { ArtistCommissionSetupItem } from './你的实体文件路径';

// 假设需要查询的艺术家ID为targetArtistId
const setupTreeRepo = getTreeRepository(ArtistCommissionSetupItem);
const commissionSetupTrees = await setupTreeRepo.findTrees({
  where: {
    artist: { id: targetArtistId }
  }
});

// 直接将commissionSetupTrees赋值给艺术家对象的commissionSetupItems字段即可

如果需要同时返回艺术家的其他基础字段,先单独查询Artist实体的基础信息,再把树形结构拼接到对应字段即可,逻辑比手动写join更简洁。

方案2:手动转换扁平查询结果为树形结构

如果你需要保留现有leftJoinAndSelect的查询逻辑,不想修改原有查询代码,可以通过转换函数把扁平数组转为嵌套树形结构:

function flatToTree(flatList: ArtistCommissionSetupItem[]): ArtistCommissionSetupItem[] {
  const idToItemMap = new Map<number, ArtistCommissionSetupItem>();
  // 初始化所有节点的childrens数组,建立id映射
  flatList.forEach(item => {
    idToItemMap.set(item.id, { ...item, childrens: item.childrens ?? [] });
  });

  const rootNodes: ArtistCommissionSetupItem[] = [];
  flatList.forEach(item => {
    // 无父节点的为根节点
    if (!item.parent?.id) {
      rootNodes.push(idToItemMap.get(item.id)!);
      return;
    }
    // 把当前节点插入对应父节点的childrens数组
    const parentNode = idToItemMap.get(item.parent.id);
    if (parentNode) {
      parentNode.childrens.push(idToItemMap.get(item.id)!);
    }
  });
  return rootNodes;
}

// 使用示例
const flatSetupItems = // 你通过leftJoinAndSelect查询得到的扁平数组
const commissionSetupItems = flatToTree(flatSetupItems);

注意使用该方案时,你现有的leftJoinAndSelect查询需要关联返回parent字段的id,否则转换函数无法识别父子关联关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:24:04