You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何编写MongoDB查询:按年份分组统计指定月份的_id数量

修正后的MongoDB聚合查询实现需求

首先,咱们来梳理下你的需求:要统计1月份的文档数量,并且按年份分组,等价于SQL语句select count(_id), year from table where month="1" group by year

你的原查询有两个核心问题:

  • 直接用new Date("$displayDate")无法正确解析MongoDB中的字段值,得用MongoDB内置的日期处理操作符来提取月份和年份
  • 没有先过滤出1月份的数据,反而把所有月份都做了分组,不符合你要的精准统计需求

情况1:displayDate字段是MongoDB原生Date类型

如果你的displayDate本身就是Date类型,直接用$month$year操作符即可,正确的聚合查询如下:

db.collection.aggregate([
  // 第一步:过滤出1月份的文档
  {
    $match: {
      $expr: { $eq: [{ $month: "$displayDate" }, 1] }
    }
  },
  // 第二步:按年份分组,统计每组的文档数量
  {
    $group: {
      _id: { year: { $year: "$displayDate" } },
      count: { $sum: 1 }
    }
  },
  // 可选:调整输出字段名,让结果更贴近SQL的输出格式
  {
    $project: {
      _id: 0,
      year: "$_id.year",
      count: 1
    }
  }
])

情况2:displayDate字段是字符串类型(比如"2024-01-15")

如果displayDate是字符串格式,需要先把它转换成Date类型,再提取月份和年份:

db.collection.aggregate([
  // 先把字符串转成Date类型,再过滤1月份的文档
  {
    $match: {
      $expr: { $eq: [{ $month: { $toDate: "$displayDate" } }, 1] }
    }
  },
  // 按年份分组统计数量
  {
    $group: {
      _id: { year: { $year: { $toDate: "$displayDate" } } },
      count: { $sum: 1 }
    }
  },
  // 可选:调整输出字段名
  {
    $project: {
      _id: 0,
      year: "$_id.year",
      count: 1
    }
  }
])

各阶段作用说明

  • $match:对应SQL的where month="1",精准过滤出1月份的文档,减少后续分组的数据处理量
  • $group:对应SQL的group by year,按年份分组并统计每组的文档数量($sum:1等价于SQL里的count(_id)
  • 可选的$project:把结果中的_id.year重命名为year,移除默认的_id字段,让输出格式更符合你的预期

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

火山引擎 最新活动