MongoDB中如何根据同集合内的ID获取数组关联文档详情
解决MongoDB中关联字段替换为完整文档的问题
要实现把linkedBy数组里的storyId替换成对应完整文档,用MongoDB的聚合框架就能轻松搞定,核心思路是通过自关联查询获取关联文档,再映射替换原数组字段。
假设你的集合名为stories,直接用下面的聚合查询即可:
db.stories.aggregate([ // 第一步:自关联查询,获取所有linkedBy对应的完整文档 { $lookup: { from: "stories", let: { linkedIds: "$linkedBy" }, pipeline: [ { $match: { $expr: { $in: [ { $toInt: "$storyId" }, // 统一类型:把字符串storyId转成数字匹配linkedBy里的数字 "$$linkedIds" ] } } } ], as: "linkedStories" } }, // 第二步:将原linkedBy数组替换为对应的完整文档 { $addFields: { linkedBy: { $map: { input: "$linkedBy", as: "id", in: { $arrayElemAt: [ { $filter: { input: "$linkedStories", cond: { $eq: [{ $toInt: "$$this.storyId" }, "$$id"] } } }, 0 // 取过滤后的第一个元素(每个storyId唯一) ] } } } } }, // 第三步:移除临时生成的linkedStories字段 { $project: { linkedStories: 0 } } ])
关键步骤解释:
$lookup自关联:通过子管道筛选出当前文档linkedBy数组中所有storyId对应的完整文档,临时存到linkedStories字段里。这里的$toInt是为了匹配示例中storyId(字符串)和linkedBy元素(数字)的类型差异,如果你的数据类型一致(比如都是字符串),可以去掉这个转换。$map+$filter替换数组:遍历原linkedBy数组的每个ID,从linkedStories中找到对应的完整文档,替换原ID元素。$project清理字段:移除临时的linkedStories,让结果结构更整洁。
执行后得到的结果就是你预期的格式:
{ "_id" : ObjectId("6130f4f16dc8c60fa554c37e"), "storyId" : "101", "storyTitle" : "story 1", "storyPriority" : "", "storyPoints" : "0", "linkedBy" : [] }, { "_id" : ObjectId("2345f4f16dc8c60fa554c37e"), "storyId" : "102", "storyTitle" : "story 2", "storyPriority" : "", "storyPoints" : "0", "linkedBy" : [ { "_id" : ObjectId("6130f4f16dc8c60fa554c37e"), "storyId" : "101", "storyTitle" : "story 1", "storyPriority" : "", "storyPoints" : "0", "linkedBy" : [] } ] }
内容的提问来源于stack exchange,提问作者Tasneem Desai
相关产品推荐
相关产品推荐

