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

如何使用JavaScript递归遍历Node.js环境下Mongoose不限层级分类树形结构

实现不限层级分类树形结构的方案

最优方案:全量查询+内存组装(推荐)

该方案仅需1次数据库查询,避免N+1查询性能问题,不受分类层数限制,时间复杂度为O(n),性能远高于递归查询数据库的方案。

async function getCategoryTree() {
  // 1. 一次性查询全部分类数据
  const allCategories = await Category.find().lean()
  // 2. 初始化_id到分类对象的映射、根分类数组
  const categoryMap = {}
  const rootCategories = []
  // 先把所有分类存入映射表,同时提前为每个分类初始化children子数组
  allCategories.forEach(cat => {
    categoryMap[cat._id.toString()] = { ...cat, children: [] }
  })
  // 3. 遍历所有分类,组装父子层级关系
  allCategories.forEach(cat => {
    const currentCat = categoryMap[cat._id.toString()]
    if (cat._mother_category) {
      // 存在父分类,将当前分类推入父分类的children数组
      const motherCat = categoryMap[cat._mother_category.toString()]
      if (motherCat) {
        motherCat.children.push(currentCat)
      }
    } else {
      // 无父分类,属于根层级节点
      rootCategories.push(currentCat)
    }
  })
  return rootCategories
}

// 调用示例
const categoryTree = await getCategoryTree()
console.log(categoryTree) // 输出完整的不限层级分类树

返回的rootCategories即为完整的多层级分类树,每个节点的children数组存储了它的所有子分类,支持任意深度的层级结构。

备选方案:递归查询数据库(仅适合数据量极小的场景)

如果分类数据量特别大、全量查询内存占用过高,可以采用递归查询方案,缺点是分类层数越多数据库查询次数越多,性能较低。

async function getCategoryWithChildren(parentId = null) {
  const query = parentId ? { _mother_category: parentId } : { _mother_category: { $exists: false } }
  const categories = await Category.find(query).lean()
  // 递归查询每个分类的子分类
  for (const cat of categories) {
    cat.children = await getCategoryWithChildren(cat._id)
  }
  return categories
}

// 调用示例
const categoryTree = await getCategoryWithChildren()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 11:54:02