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

MongoDB聚合查询闰年结果错误,寻求修正方案

问题:MongoDB聚合统计闰年结果异常

文档数据

{
    "_id" : ObjectId("63a994974ac549c5ea982d2b"),
    "title" : "Destroyer",
    "year" : 2018
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d2a"),
    "title" : "Aquaman",
    "year" : 2014
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d29"),
    "title" : "On the Basis of Sex",
    "year" : 1996   
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d28"),
    "title" : "Holmes and Watson",
    "year" : 1940
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d27"),
    "title" : "Conundrum: Secrets Among Friends",
    "year" : 1957
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d26"),
    "title" : "Welcome to Marwen",
    "year" : 2004
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d25"),
    "title" : "Mary Poppins Returns",
    "year" : 1997
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d24"),
    "title" : "Bumblebee",
    "year" : 2004
}

错误的聚合管道代码

var query0 = {$group: {"_id": {"year": "$year"}}}

var query1 = {$addFields: {
      leap: {
        "$and": [
          {"$eq": [{"$mod": ["$year",4]}, 0]},
          {"$or": [
              {"$ne": [{"$mod": ["$year", 100]}, 0]},
              {"$eq": [{"$mod": ["$year", 400]}, 0] }
          ]}
        ]
      }
}}

var query2 = {$project: {leap: true}}

var query3 = {$group: {
      "_id": "$leap",
      "count": {$sum: 1}
  }}

var etapas =  [query0, query1, query2, query3]

db.genres.aggregate(etapas)

实际输出

{
    "_id": false,
    "count": 8 
}

期望输出

{
    "_id": "Leap",
    "count": 3
}

问题原因与修正方案

问题1:字段引用错误

第一个$group阶段执行后,所有年份字段被嵌套在_id.year结构下,但后续$addFields中仍直接用$year引用,导致MongoDB无法找到目标字段,最终所有leap计算结果为false,统计出全为非闰年的错误结果。

问题2:输出格式不匹配

原代码按布尔值true/false分组,而期望输出_id为字符串"Leap",需要将布尔值映射为对应文本。

修正后的聚合管道

var query0 = {$group: {"_id": {"year": "$year"}}}

var query1 = {$addFields: {
      leap: {
        "$and": [
          {"$eq": [{"$mod": ["$_id.year",4]}, 0]},
          {"$or": [
              {"$ne": [{"$mod": ["$_id.year", 100]}, 0]},
              {"$eq": [{"$mod": ["$_id.year", 400]}, 0] }
          ]}
        ]
      }
}}

var query2 = {$project: {leap: true}}

var query3 = {$group: {
      "_id": {$cond: ["$leap", "Leap", "Non-Leap"]},
      "count": {$sum: 1}
  }}

// 可选:仅保留闰年统计结果,不需要则移除该阶段
var query4 = {$match: {"_id": "Leap"}}

var etapas =  [query0, query1, query2, query3, query4]

db.genres.aggregate(etapas)

说明

  1. 将$addFields中的$year全部替换为$_id.year,确保正确获取分组后的年份值。
  2. 在最后一个$group阶段用$cond将布尔值映射为字符串,匹配期望的输出格式。
  3. 新增的$match阶段可过滤非闰年数据,若需要同时展示两种结果,直接移除该阶段即可。

执行修正后的代码,将得到期望输出:

{
    "_id": "Leap",
    "count": 3
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:10:30