You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Mongoid对关联的Campaign与Media文档执行聚合操作?

解决Campaign聚合获取Media总预算的问题

你在聚合操作里踩了个常见的Mongoid关联坑——belongs_to关联默认只会存储关联对象的_id(比如media_id字段),并不会把整个Media文档嵌套进Campaign里,所以直接用"$media.budget"是拿不到值的,而且$sum的写法也不符合MongoDB聚合语法。下面给你修正后的解决方案:

核心思路

要获取Media的预算,得先通过$lookup把Campaign关联的Media数据拉取过来,再去重(避免同一个Media被多个Campaign重复计算),最后完成聚合统计。

场景1:获取所有关联活跃Campaign的Media总预算

results = Campaign.collection.aggregate([
  # 第一步:筛选状态为active的Campaign
  { '$match': { state: 'active' } },
  # 第二步:关联Media集合,拉取对应Media的完整数据
  { '$lookup': {
      from: 'media', # 注意:这里是Media模型对应的集合名,Mongoid默认是复数小写,自定义过集合名要修改
      localField: 'media_id', # Campaign中存储Media关联ID的字段,默认是media_id,自定义foreign_key需对应调整
      foreignField: '_id',
      as: 'media'
    }
  },
  # 第三步:展开关联得到的media数组($lookup返回的是数组,即使一个Campaign对应一个Media)
  { '$unwind': '$media' },
  # 第四步:按Media ID去重,确保每个Media只被计算一次
  { '$group': {
      '_id': '$media._id',
      'media_budget': { '$first': '$media.budget' }
    }
  },
  # 第五步:计算所有Media的总预算
  { '$group': {
      '_id': null,
      'total_media_budget': { '$sum': '$media_budget' }
    }
  }
])

场景2:按日期分组,统计每日关联活跃Campaign的Media总预算

如果你的需求是按date字段分组统计,同样需要先去重同一个Media在同一天的多个Campaign:

results = Campaign.collection.aggregate([
  { '$match': { state: 'active' } },
  { '$lookup': {
      from: 'media',
      localField: 'media_id',
      foreignField: '_id',
      as: 'media'
    }
  },
  { '$unwind': '$media' },
  # 先按日期+Media ID分组,确保同一Media在同一天只被计算一次
  { '$group': {
      '_id': { date: '$date', media_id: '$media._id' },
      'single_budget': { '$first': '$media.budget' }
    }
  },
  # 再按日期分组求和
  { '$group': {
      '_id': '$_id.date',
      'daily_total_budget': { '$sum': '$single_budget' }
    }
  }
])

原代码的问题说明

  1. 字段引用错误:Campaign文档里不存在media.budget字段,belongs_to关联仅存储media_id,不会嵌套整个Media文档,必须通过$lookup关联Media集合才能获取预算值。
  2. $sum语法错误:$sum需要接收一个数值字段,你写的{ 'media': '$budget' }是键值对格式,不符合MongoDB聚合的语法要求。

注意事项

  • 确认Media集合名称:如果Media模型自定义了集合名(比如self.collection_name = 'custom_media'),要把$lookup里的from改成对应的名称。
  • 确认关联字段:如果Campaign模型里设置了belongs_to :media, foreign_key: :custom_media_id,要把localField改成custom_media_id。

内容的提问来源于stack exchange,提问作者WagnerMatosUK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:43:39