MongoDB按userId匹配比较日期判断是否执行insertOne插入的实现问题
MongoDB 按日期条件插入记录实现方案
原方案错误原因
你之前使用aggregate管道的方案存在两个核心问题:
- aggregate是纯查询操作,本身不具备写入能力,无法实现插入数据的需求
- 管道逻辑没有预先过滤目标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
相关产品推荐
相关产品推荐

