如何在Node.js Express中通过ID查询MongoDB文件夹及其子项?
问题
我在MongoDB中存储了如下层级结构的文件/文件夹数据:
[ { "_id": 1, "name": "ABC", "parentID": null }, { "_id": 2, "name": "ABC.txt", "parentID": 1 }, { "_id": 3, "name": "ABCD", "parentID": 1 }, { "_id": 4, "name": "ABC 3", "parentID": 3 }, { "_id": 5, "name": "ABCDFE", "parentID": null } ]
需要在Node.js Express中编写查询,根据指定文件夹ID(比如ID为1的文件夹),获取该文件夹及其所有子项,忽略其他顶级文件夹(比如ID为5的文件夹),期望返回结果如下:
[ { "_id": 1, "name": "ABC", "parentID": null }, { "_id": 2, "name": "ABC.txt", "parentID": 1 }, { "_id": 3, "name": "ABCD", "parentID": 1 }, { "_id": 4, "name": "ABC 3", "parentID": 3 } ]
当前代码如下:
exports.getProofFolderById = async (req, res, next) => { const file = await Proof.find({ _id: req.params.id}) if(!file) { next(new Error("Folder not found!!!")) } res.status(200).json({ success: true, file }) }
恳请帮忙修改代码实现需求,谢谢❤️
解决方案
要实现获取指定文件夹及其所有层级子项的需求,可利用MongoDB的聚合查询,通过$graphLookup操作符递归查询所有子节点,修改后的代码及说明如下:
修改后的完整代码
exports.getProofFolderById = async (req, res, next) => { const folderId = req.params.id; // 先验证目标文件夹是否存在 const targetFolder = await Proof.findById(folderId); if (!targetFolder) { return next(new Error("Folder not found!!!")); } // 聚合查询获取当前文件夹及所有子项 const result = await Proof.aggregate([ // 匹配目标文件夹 { $match: { _id: folderId } }, // 递归查询所有层级的子节点 { $graphLookup: { from: "proofs", // 对应MongoDB集合名称,需与你的Model集合名一致 startWith: "$_id", connectFromField: "_id", connectToField: "parentID", as: "children", maxDepth: 100 // 根据实际层级调整最大递归深度 } }, // 展开子节点数组为平级文档 { $unwind: { path: "$children", preserveNullAndEmptyArrays: true } }, // 将子节点或原文件夹作为根文档 { $replaceRoot: { newRoot: { $cond: { if: "$children", then: "$children", else: "$$ROOT" } } } }, // 合并目标文件夹本身到结果集 { $unionWith: { coll: "proofs", pipeline: [{ $match: { _id: folderId } }] } }, // 去重,避免目标文件夹重复出现 { $group: { _id: "$_id", doc: { $first: "$$ROOT" } } }, { $replaceRoot: { newRoot: "$doc" } }, // 可选:按parentID排序,保持层级展示顺序 { $sort: { parentID: 1, _id: 1 } } ]); res.status(200).json({ success: true, files: result }); };
关键逻辑说明
- 文件夹存在性校验:通过
findById先确认目标文件夹存在,避免无效查询。 - $graphLookup递归查询:核心操作,从指定集合中递归查找所有以当前文件夹
_id为parentID的节点,以及这些节点的子节点,直到达到maxDepth限制。 - 结果格式化:通过
$unwind展开嵌套的子节点数组,$unionWith将原文件夹文档加入结果,最后去重并排序,得到与期望一致的平级结构。
注意事项
- 确保
from字段的值是你的MongoDB集合实际名称(通常Model对应的集合名为小写复数,比如Proof模型对应proofs集合)。 maxDepth可根据业务场景调整,防止无限递归。- 若需要返回嵌套层级结构,可去掉
$unwind及后续的平级处理步骤,直接返回包含children字段的嵌套文档。
内容的提问来源于stack exchange,提问作者Đạt Huỳnh
相关产品推荐
相关产品推荐

