咨询MongoDB中多文档按指定键分组联合字段的合并实现方法
MongoDB 跨文档键匹配合并实现方案
前置语法修正
先把原始文档、预期输出里的语法问题先修正,否则JSON无法正常解析:
- Document2、Document3存在字符串未闭合问题:
url字段的取值末尾缺少双引号,且两个文档本身缺少最外层的对象包裹,修正后的合法结构如下:- 修正后的Document2:
{ "Deal": { "name": "abc", "url" : "www.abc.com", "email": [ "abc@gmail.com"], "total": 2 } } - 修正后的Document3:
{ "Deal": { "name": "xyz", "url" : "www.googl.com", "email": [ "xyz@gmail.com"], "total": 25 } }
- 修正后的Document2:
- 原预期输出存在结构语法错误:直接嵌套两层大括号没有数组包裹,修正后的合法输出为包含两个合并结果的数组结构。
匹配逻辑说明
整个合并过程的关联锚点完全对齐提出的联合规则:
- 从Document1的
data.Inside_data.project路径下取出abc、xyz两个子键的嵌套值(包含alpha、beta两个字段) - 用子键的取值,和Document2、Document3里
Deal.name字段的取值做精确匹配 - 匹配成功后,把Deal下的所有字段、project下对应键的所有字段拍平到同一层级,同时把Deal里数组格式的email转成单字符串,完全对齐预期的输出结构。
可直接运行的聚合管道代码
直接把集合名替换成对应业务集合名即可运行:
db.your_business_collection.aggregate([ // 筛选出Document1(带project嵌套结构的主文档) { $match: { "data.Inside_data.project": { $exists: true } } }, // 将project对象转成键值对数组,方便拆分 { $project: { project_items: { $objectToArray: "$data.Inside_data.project" }, _id: 0 } }, // 把每个project子键拆成独立的文档流 { $unwind: "$project_items" }, // 关联同集合内的Deal文档:匹配键和Deal.name相等 { $lookup: { from: "your_business_collection", localField: "project_items.k", foreignField: "Deal.name", as: "matched_deal" } }, // 把lookup返回的数组拆成单对象 { $unwind: "$matched_deal" }, // 拍平所有字段,处理email格式 { $replaceRoot: { newRoot: { name: "$matched_deal.Deal.name", url: "$matched_deal.Deal.url", email: { $first: "$matched_deal.Deal.email" }, total: "$matched_deal.Deal.total", alpha: "$project_items.v.alpha", beta: "$project_items.v.beta" } } } ])
最终运行输出结果
[ { "name": "abc", "url": "www.abc.com", "email": "abc@gmail.com", "total": 2, "alpha": 4, "beta": 45 }, { "name": "xyz", "url": "www.googl.com", "email": "xyz@gmail.com", "total": 25, "alpha": 214, "beta": 431 } ]
内容的提问来源于stack exchange,提问作者bc110402922
相关产品推荐
相关产品推荐

