MongoDB中如何对嵌套对象递归应用投影并生成路径字段?
MongoDB 多层嵌套文档的递归投影与路径计算实现
我在MongoDB中有如下多层嵌套的数据结构:
{ _id: ObjectId("123"), name: "Top level", someData: "hello world", parent: null, children: { "456": { _id: ObjectId("456"), name: "Nested Obj", parent: "123", someData: "lorem ipsum", children: { "963": { _id: ObjectId("963"), name: "2nd level nesting", parent: "456", someData: "some data", children: {} } } }, "798": { _id: ObjectId("798"), parent: "123", name: "Another entry", someData: "more data here", children: {}, } } }
需要实现两个需求:
- 对所有嵌套对象递归应用投影,仅保留
_id和name字段 - 创建计算字段
path,存储每个对象的访问路径(顶层路径为空数组,子节点路径包含所有父节点的_id)
期望查询结果如下:
{ _id: ObjectId("123"), name: "Top level", path: [], children: { "456": { _id: ObjectId("456"), name: "Nested Obj", path: ["123"], children: { "963": { _id: ObjectId("963"), name: "2nd level nesting", path: ["123", "456"], children: {} } } }, "798": { _id: ObjectId("798"), name: "Another entry", path: ["123"], children: {}, } } }
实现方案
可以通过MongoDB 4.4+版本支持的$function自定义递归函数,结合聚合框架完成需求:
db.collection.aggregate([ { $addFields: { path: [], children: { $function: { body: function(children, parentPath) { // 递归处理单个节点的函数 const processNode = (node, currentPath) => { // 执行投影,只保留指定字段 const processedNode = { _id: node._id, name: node.name, path: currentPath, children: {} }; // 遍历子节点,递归处理 Object.keys(node.children).forEach(key => { processedNode.children[key] = processNode( node.children[key], [...currentPath, node._id.toString()] ); }); return processedNode; }; const processedChildren = {}; // 遍历顶层children中的所有节点 Object.keys(children).forEach(key => { processedChildren[key] = processNode( children[key], [...parentPath, this._id.toString()] ); }); return processedChildren; }, args: ["$children", "$path"], lang: "js" } } } }, // 顶层文档投影,过滤不需要的字段 { $project: { _id: 1, name: 1, path: 1, children: 1 } } ])
说明
- 递归投影:自定义的
processNode函数会对每个节点只保留_id、name、children字段,过滤掉someData、parent等不需要的内容 - 路径计算:每个节点的
path由父节点的路径加上父节点的_id拼接而成,顶层节点的path初始化为空数组 - 版本要求:必须使用MongoDB 4.4及以上版本,因为
$function是该版本引入的特性
内容的提问来源于stack exchange,提问作者Felipe
相关产品推荐
相关产品推荐

