MongoDB同一集合不同结构文档按commonCodeId合并生成自定义文档方法
MongoDB同集合异构文档按公共字段合并方案
你可以通过MongoDB聚合管道实现需求,核心用到$group和$mergeObjects操作符,以下是可直接运行的聚合查询:
db.collection.aggregate([ // 筛选目标commonCodeId对应的所有文档,可按需调整匹配规则 { $match: { commonCodeId: 1234 } }, // 按公共字段commonCodeId分组,拆分基础文档和扩展字段文档 { $group: { _id: "$commonCodeId", // 提取_id为1的文档作为合并基础 baseDoc: { $first: { $cond: [{$eq: ["$_id", 1]}, "$$ROOT", null] } }, // 收集其余需要提取字段的文档 extraDocs: { $push: { $cond: [{$ne: ["$_id", 1]}, "$$ROOT", null] } } } }, // 过滤扩展文档数组中的空值 { $addFields: { extraDocs: { $filter: { input: "$extraDocs", cond: {$ne: ["$$this", null]} } } } }, // 合并文档生成自定义结构 { $replaceRoot: { newRoot: { $mergeObjects: [ "$baseDoc", {$mergeObjects: "$extraDocs"}, // 生成新的_id,可替换为你自定义的_id值 {_id: ObjectId()} ] } } }, // 可选:如果需要将结果持久化到新集合,取消注释下面一行并修改集合名 // {$out: "merged_custom_docs"} ])
关键说明
- 字段优先级:
$mergeObjects操作符会优先保留排在前面的对象的同名字段,上面的写法保证了_id为1的基础文档字段不会被其他文档覆盖,仅补充基础文档不存在的字段 - 精准字段提取:如果不需要合并其余文档的全部字段,仅需要提取指定字段,可以修改
$group阶段的extraDocs逻辑,按需返回字段即可,示例如下:
extraDocs: { $push: { $switch: { branches: [ {case: {$eq: ["$_id", 2]}, then: {fieldINeedToAddInCustomDocument: "$fieldINeedToAddInCustomDocument"}}, {case: {$eq: ["$_id", 3]}, then: {anotherFieldINeedToAddInCustomDocument: "$anotherFieldINeedToAddInCustomDocument"}} ], default: null } } }
- 版本要求:
$mergeObjects接收数组参数的特性需要MongoDB 4.4及以上版本支持,低版本可将多层$mergeObjects展开为顺序传入参数的形式即可兼容。
内容的提问来源于stack exchange,提问作者jewa
相关产品推荐
相关产品推荐

