如何在MongoDB所有嵌套文档中添加字段
解决MongoDB树形结构文档批量添加id字段的问题
你的写法无效是因为children是数组字段,不能直接通过children.id这种路径批量给数组内的每个元素添加字段,必须用数组遍历操作处理每个子节点,同时嵌套的子数组也要递归处理。
方案1:固定层级的树形结构处理
如果你的树形结构层级固定(比如示例中的两层子节点),可以用$map结合$mergeObjects逐层处理:
db.collection.aggregate([ { $addFields: { // 给根节点添加id字段 id: "$_id", // 处理第一层children数组 children: { $map: { input: "$children", as: "child", in: { $mergeObjects: [ "$$child", // 保留原子节点的所有字段 { id: "$$child._id" }, // 添加id字段 // 处理子节点的children数组 { children: { $map: { input: "$$child.children", as: "grandchild", in: { $mergeObjects: [ "$$grandchild", { id: "$$grandchild._id" } ] } } } } ] } } } } } ])
方案2:通用递归处理(支持任意层级)
如果你的树形结构层级不固定,推荐用MongoDB 4.4+支持的$function编写递归函数,自动遍历所有层级的节点添加字段:
db.collection.aggregate([ { $addFields: { id: "$_id", children: { $function: { body: function(children) { // 定义递归函数,给单个节点添加id并处理子节点 const addIdToNode = (node) => { node.id = node._id; if (node.children && node.children.length > 0) { node.children = node.children.map(child => addIdToNode(child)); } return node; }; // 遍历第一层children数组,逐个处理 return children.map(child => addIdToNode(child)); }, args: ["$children"], lang: "js" } } } } ])
关键说明
$map用于遍历数组中的每个元素,确保每个子节点都能被处理$mergeObjects用于将原节点的字段和新添加的id字段合并,避免覆盖原有数据- 递归方案中的
addIdToNode函数会自动处理所有嵌套层级的子节点,无需手动编写多层逻辑
内容的提问来源于stack exchange,提问作者uchiha itachi
相关产品推荐
相关产品推荐

