MongoDB如何在嵌套对象数组中使用$mergeObjects聚合
解决MongoDB嵌套数组聚合合并问题
基于你提供的两个集合数据,要完成嵌套tenants数组的字段合并,可通过以下聚合管道实现目标结果:
db.app.aggregate([ // 展开provider_tenants数组,逐个处理每个租户提供商 { $unwind: "$provider_tenants" }, // 关联details_provider集合,匹配对应提供商的详情 { $lookup: { from: "details_provider", localField: "provider_tenants._id", foreignField: "_id", as: "provider_details" } }, // 展开关联得到的详情数组(一对一匹配,仅单个元素) { $unwind: "$provider_details" }, // 合并嵌套tenants的字段,并补全提供商名称 { $addFields: { "provider_tenants.name": "$provider_details.name", "provider_tenants.tenants": { $map: { input: "$provider_tenants.tenants", as: "app_tenant", in: { $mergeObjects: [ "$$app_tenant", { $arrayElemAt: [ { $filter: { input: "$provider_details.tenants", cond: { $eq: ["$$this._id", "$$app_tenant._id"] } } }, 0 ] } ] } } } } }, // 移除临时生成的provider_details字段 { $unset: "provider_details" }, // 重新分组恢复原文档结构 { $group: { _id: "$_id", name: { $first: "$name" }, provider_tenants: { $push: "$provider_tenants" } } } ])
各阶段说明:
- $unwind: "$provider_tenants":将app文档中的
provider_tenants数组拆分为独立文档,确保每个提供商条目能单独关联详情数据。 - $lookup:通过提供商的
_id,从details_provider集合中拉取对应的名称和租户详情,结果存入临时数组provider_details。 - $unwind: "$provider_details":展开临时详情数组,方便直接提取其中的字段。
- $addFields:
- 把
details_provider中的提供商名称赋值给provider_tenants的name字段; - 使用
$map遍历app中每个租户条目,配合$filter找到details_provider中_id匹配的租户数据,再通过$mergeObjects将两个来源的字段(path、name、redirect_uri)合并为一个完整的租户对象。
- 把
- $unset:清理临时字段
provider_details,精简输出结构。 - $group:按app文档的
_id重新分组,将拆分的provider_tenants条目重新组合为数组,恢复原始的文档层级结构。
内容的提问来源于stack exchange,提问作者Chotinun Puangperm
相关产品推荐
相关产品推荐

