MongoDB聚合查询优化:如何返回独立的tenant与campaign对象?
MongoDB聚合查询:将关联的Tenant与Campaign返回为独立顶级对象
你可以通过在现有聚合流程中添加**$project**阶段,直接重构文档结构,把tenant和campaign转为顶级独立对象,同时将campaign数组转为单个文档。
完整聚合查询代码
[ // 1. 匹配指定domain的tenant { $match: { 'domains.name': '<DOMAIN_HERE>' } }, // 2. 关联并过滤指定slug的campaign { $lookup: { from: 'campaigns', localField: '_id', foreignField: 'tenantId', as: 'campaign', pipeline: [{ $match: { slug: '<SLUG_HERE>' } }] } }, // 3. 重构文档结构 { $project: { // 将原tenant文档(排除campaign数组)封装到tenant字段 tenant: { $mergeObjects: [$$ROOT, { campaign: "$$REMOVE" }] }, // 将campaign数组转为单个对象(取第一个元素) campaign: { $first: "$campaign" } } } ]
关键阶段说明
- $mergeObjects + $$REMOVE:通过
$$ROOT获取当前文档的所有字段,再用campaign: "$$REMOVE"移除lookup生成的campaign数组,确保tenant对象是纯净的原tenant文档。 - $first:因为你的lookup pipeline已经通过slug过滤出唯一的campaign,用
$first直接从数组中提取单个文档,避免后续代码处理数组。
返回结果示例
{ tenant: { _id: ObjectId('60d21b4667d0d8992e610c85'), domains: [{ name: 'example.com' }], // 其他tenant字段... }, campaign: { _id: ObjectId('60d21b8967d0d8992e610c86'), slug: 'summer-sale-2024', tenantId: ObjectId('60d21b4667d0d8992e610c85'), // 其他campaign字段... } }
可选优化(处理campaign不存在的情况)
如果需要确保返回的结果中一定存在匹配的campaign,可以在最后添加一个$match阶段过滤掉campaign为null的文档:
{ $match: { campaign: { $ne: null } } }
内容的提问来源于stack exchange,提问作者Patrik Šimunič
相关产品推荐
相关产品推荐

