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

如何在MongoDB中基于day和month字段查询明日过生日的用户

查询明日过生日的MongoDB用户方案

当然可以通过处理birthDay和birthMonth字段来筛选明日过生日的用户,甚至不用完全生成DateTime字段也能实现高效查询,以下是两种可行方案:

方案一:直接匹配月日(推荐,性能更优)

不需要生成额外DateTime字段,直接通过表达式匹配明日的月份和日期,同时处理跨年边界情况(比如12月31日的次日是1月1日):

// 获取明日的日期信息
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const tomorrowMonth = tomorrow.getMonth() + 1; // MongoDB月份为1-12,JS原生是0-11,需加1
const tomorrowDay = tomorrow.getDate();

// 构建查询条件
db.users.find({
  $expr: {
    $or: [
      // 普通情况:月日完全匹配
      {
        $and: [
          { $eq: ["$aboutPage.birthMonth", tomorrowMonth] },
          { $eq: ["$aboutPage.birthDay", tomorrowDay] }
        ]
      },
      // 跨年情况:今日是12月31日,明日是1月1日
      {
        $and: [
          { $eq: ["$aboutPage.birthMonth", 1] },
          { $eq: ["$aboutPage.birthDay", 1] },
          { $eq: [tomorrowMonth, 1] },
          { $eq: [tomorrowDay, 1] }
        ]
      }
    ]
  }
});

方案二:生成DateTime字段后筛选

如果一定要生成DateTime字段,可以用聚合管道先构造生日日期(基于当前年份),再和明日日期对比,同样需要处理跨年场景:

const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
// 格式化明日为yyyy-MM-dd字符串,忽略时间部分
const tomorrowStr = `${tomorrow.getFullYear()}-${String(tomorrow.getMonth()+1).padStart(2, '0')}-${String(tomorrow.getDate()).padStart(2, '0')}`;

db.users.aggregate([
  {
    $addFields: {
      // 构造当前年份的生日日期
      birthDate: {
        $dateFromString: {
          dateString: {
            $concat: [
              { $toString: new Date().getFullYear() },
              "-",
              { $toString: { $padLeft: ["$aboutPage.birthMonth", 2, "0"] } },
              "-",
              { $toString: { $padLeft: ["$aboutPage.birthDay", 2, "0"] } }
            ]
          }
        }
      }
    }
  },
  {
    $addFields: {
      // 处理跨年生日:如果当前生日日期已过,自动加一年
      adjustedBirthDate: {
        $cond: {
          if: { $lt: ["$birthDate", new Date()] },
          then: { $add: ["$birthDate", 31536000000] }, // 加一年(毫秒级近似值)
          else: "$birthDate"
        }
      }
    }
  },
  {
    $match: {
      // 匹配adjustedBirthDate等于明日的日期(忽略时间)
      $expr: {
        $eq: [
          { $dateToString: { format: "%Y-%m-%d", date: "$adjustedBirthDate" } },
          tomorrowStr
        ]
      }
    }
  }
]);

注意:方案一避免了聚合管道的额外计算,查询性能更好,更适合生产环境使用;方案二适合需要生成生日DateTime字段做后续处理的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:00:06