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

MongoDB按userId匹配比较日期判断是否执行insertOne插入的实现问题

MongoDB 按日期条件插入记录实现方案

原方案错误原因

你之前使用aggregate管道的方案存在两个核心问题:

  1. aggregate是纯查询操作,本身不具备写入能力,无法实现插入数据的需求
  2. 管道逻辑没有预先过滤目标userId的记录,也没有正确匹配日期范围,导致返回结果不符合预期

正确实现方案

使用MongoDB原生的updateOne+upsert特性即可实现需求,不需要复杂的聚合管道,核心是利用$setOnInsert操作符,只有触发插入时才会写入对应字段,匹配到已有记录时不会做任何修改。

实现代码

// 取出参数
const userId = req.user._id;
const currentDate = new Date();
const ip = req.socket.remoteAddress;

// 计算当日时间范围:今日0点到明日0点
const startOfToday = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
const startOfTomorrow = new Date(startOfToday.getTime() + 24 * 60 * 60 * 1000);

db.collection.updateOne(
  // 筛选条件:匹配对应用户当天的已有记录
  {
    userId: userId,
    date: {
      $gte: startOfToday,
      $lt: startOfTomorrow
    }
  },
  // 仅插入时执行的字段赋值
  {
    $setOnInsert: {
      userId: userId,
      date: currentDate,
      ip: ip
    }
  },
  // 开启upsert:匹配不到记录时自动插入新文档
  { upsert: true }
)

效果验证

  • 传入参数为userId: ObjectId("61965bead6af120015c7e9cc")、date: ISODate("2021-11-25T16:08:35.606Z")时,筛选条件匹配到已有记录,不执行任何操作
  • 传入参数为userId: ObjectId("61965bead6af120015c7e9cc")、date: ISODate("2021-11-26T16:08:35.606Z")时,筛选条件无匹配记录,触发upsert插入新文档,符合预期效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:54:11