MongoDB多集合关联分组聚合求助:按组织关联书籍等文档
MongoDB按文档类型聚合关联数据解决方案
聚合思路
从组织类型的items文档入手,通过tuples集合关联所有关联的其他items文档,再根据关联文档的type_id(对应types集合的类型名称)分类整理成chapters、books等字段。
完整聚合代码
db.items.aggregate([ // 筛选组织类型文档 { $lookup: { from: "types", localField: "type_id", foreignField: "_id", as: "type_info" } }, { $match: { "type_info.name": "Organization" } }, { $unwind: "$type_info" }, { $project: { type_info: 0 } }, // 关联tuples获取关联关系 { $lookup: { from: "tuples", localField: "_id", foreignField: "source_id", as: "related_tuples" } }, { $unwind: "$related_tuples" }, // 关联目标items文档 { $lookup: { from: "items", localField: "related_tuples.destination_id", foreignField: "_id", as: "related_items" } }, { $unwind: "$related_items" }, // 关联types获取关联文档类型名称 { $lookup: { from: "types", localField: "related_items.type_id", foreignField: "_id", as: "related_type" } }, { $unwind: "$related_type" }, // 按组织ID分组,按类型归类关联文档 { $group: { _id: "$_id", type_id: { $first: "$type_id" }, chapters: { $push: { $cond: [{ $eq: ["$related_type.name", "Chapter"] }, "$related_items", "$$REMOVE"] } }, books: { $push: { $cond: [{ $eq: ["$related_type.name", "Book"] }, "$related_items", "$$REMOVE"] } } } }, // 清理数组空值 { $addFields: { chapters: { $filter: { input: "$chapters", cond: { $ne: ["$$this", null] } } }, books: { $filter: { input: "$books", cond: { $ne: ["$$this", null] } } } } } ])
代码说明
- 先筛选出所有组织类型的
items文档,确保只处理组织节点。 - 通过两次
$lookup关联tuples获取关联关系,再拉取对应的items文档。 - 关联
types集合拿到关联文档的类型名称,用于后续分类。 - 用
$group和$cond按类型将关联文档分别存入chapters和books数组。 - 最后用
$filter清理数组中的空值,保证结果整洁。
示例输出
{ "_id" : "BE05332051E0AD282", "type_id" : "684EB00155D031225", "chapters" : [ { "_id" : "9E05332051E0AF344", "type_id" : "xxx", "name" : "某章节", // 其他章节字段... } ], "books" : [ { "_id" : "0E05333051E0A02E7", "type_id" : "BE0532A041E0AC077", "name" : "某书籍", // 其他书籍字段... } ] }
扩展提示
- 如果需要新增其他类型分类(比如Person),只需在
$group阶段添加对应字段和$cond判断即可。 - 若关联是双向的(目标文档也可能关联源组织),可调整
tuples的关联条件,同时匹配source_id和destination_id。
内容的提问来源于stack exchange,提问作者dEL
相关产品推荐
相关产品推荐

