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

如何在MongoDB聚合操作中对offers集合的多文档分组?

MongoDB聚合分组:合并同一Offer下的多门店数据

嘿,看你的文档结构,应该是想把同一个offerId对应的多个门店信息聚合到一起对吧?这刚好是MongoDB聚合框架里$group阶段的典型应用场景,我给你一步步拆解怎么实现:

核心思路:按offerId分组聚合

咱们的目标是把所有拥有相同offerId的文档合并,将每个文档里的outlets信息收集成一个数组,同时保留该优惠的起止时间。

完整聚合示例代码

db.offers.aggregate([
  // 第一阶段:按offerId分组,收集门店信息和时间
  {
    $group: {
      _id: "$offerId", // 指定分组依据为offerId
      outlets: { $push: "$outlets" }, // 将每个文档的outlets对象推入数组
      startTime: { $first: "$startTime" }, // 取该组第一个文档的startTime(假设同offer时间一致)
      endTime: { $first: "$endTime" } // 同理取endTime
    }
  },
  // 第二阶段:调整输出格式,让结果更贴合需求
  {
    $project: {
      offerId: "$_id", // 将分组用的_id重命名回offerId
      _id: 0, // 隐藏默认的_id字段
      outlets: 1, // 保留门店数组
      startTime: 1, // 保留起始时间
      endTime: 1 // 保留结束时间
    }
  }
])

代码解释

  1. $group阶段:

    • _id: "$offerId":这是分组的核心,MongoDB会把所有offerId相同的文档归为一组。
    • $push: "$outlets":把每组内每个文档的outlets对象添加到一个数组中,最终每个组会得到该offer对应的所有门店列表。
    • $first: "$startTime":如果同一个offerId的所有文档起止时间都一致,用$first取第一个文档的时间就足够;如果存在时间差异,你可以换成$addToSet(去重)或者$max/$min(取最大/最小时间)。
  2. $project阶段:
    这个阶段主要是美化输出结果——把MongoDB自动生成的_id(也就是我们用的offerId)重命名回offerId,同时隐藏不需要的_id字段,让返回的文档结构和原始文档更匹配。

扩展场景:如果需要按门店分组

如果你之后有需要按storeUuid分组,统计每个门店关联的优惠,只需要把$group的_id改成"$outlets.storeUuid",然后用$push: "$offerId"收集对应的优惠ID即可,逻辑是相通的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:44:04