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

MongoDB如何查询过去12个月各月累计店铺总数

MongoDB 过去12个月各月累计店铺数查询实现方案

集合样本结构

{
  _id: '5f3d4e5e01e06f0007335233',
  name: 'Walmart',
  createdAt: '2020-08-22T17:42:09.908+00:00'
}

现有查询能力

你当前的聚合查询已经可以获取过去12个月每月的新增店铺数量:

Shop.aggregate([{
  $match: {
     createdAt: {
      $gte: {
        $date: {{moment.utc().subtract(12, "months").startOf('day').toISOString()}}
      },
      $lt: {
        $date: {{moment.utc().startOf('day').toISOString()}}
      }
    }
  }
}, {
  $project: {
    dateParts: {
      $dateToParts: { date: '$createdAt' }
    },
    total: true,
  }
}, {
  $group: {
    _id:  {
      month: '$dateParts.month',
      year: '$dateParts.year',
    },
    numShops: { $sum: 1 },
  }
}])

现有查询仅返回单月新增数据,格式如下:

[{
  _id: {
    month:3,
    year:2021
  },
  numShops:62,
},
...
]

调整后实现累计统计的查询方案

你需要在现有聚合管道基础上新增排序、累计求和、日期格式化三个阶段即可,完整语句如下:

Shop.aggregate([
  // 原有匹配阶段:过滤过去12个月的店铺数据
  {
    $match: {
       createdAt: {
        $gte: {
          $date: {{moment.utc().subtract(12, "months").startOf('day').toISOString()}}
        },
        $lt: {
          $date: {{moment.utc().startOf('day').toISOString()}}
        }
      }
    }
  },
  // 原有日期拆分阶段
  {
    $project: {
      dateParts: {
        $dateToParts: { date: '$createdAt' }
      }
    }
  },
  // 原有分组阶段:统计每月新增店铺数
  {
    $group: {
      _id:  {
        month: '$dateParts.month',
        year: '$dateParts.year',
      },
      monthlyNew: { $sum: 1 },
    }
  },
  // 新增1:按年月正序排序,保证累加顺序正确
  {
    $sort: {
      "_id.year": 1,
      "_id.month": 1
    }
  },
  // 新增2:窗口函数实现累计求和
  {
    $setWindowFields: {
      sortBy: { "_id.year": 1, "_id.month": 1 },
      output: {
        numShops: {
          $sum: "$monthlyNew",
          window: { documents: ["unbounded", "current"] }
        }
      }
    }
  },
  // 新增3:格式化日期为 月-年 格式,调整返回字段结构
  {
    $project: {
      _id: 0,
      date: {
        $dateToString: {
          format: "%b-%Y",
          date: {
            $dateFromParts: {
              year: "$_id.year",
              month: "$_id.month",
              day: 1
            }
          }
        }
      },
      numShops: 1
    }
  }
])

结果说明

最终返回格式完全符合预期:

[
  {
    "date": "Aug-2020",
    "numShops": 100
  },
  {
    "date": "Sep-2020",
    "numShops": 230
  },
  ...
]

注意事项

  • $setWindowFields 是MongoDB 5.0版本推出的功能,如果你使用的是更早版本,可以在查询拿到每月新增数据后,在业务代码层做累加计算,逻辑完全一致。
  • 如果需要统计全历史累计(不是仅过去12个月的新增累加),可以把$match的时间范围下限去掉,匹配所有创建时间小于当前的店铺即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 19:45:02