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

Mongoose实现数组内对象存在则更新、不存在则新增的操作方法

Mongoose Streak集合当日记录更新实现方案

需求说明

在streaks数组中查询是否存在日期为当日的对象:

  • 存在则直接累加questionCount字段的数值
  • 不存在则新建一条包含当日日期的对象

集合结构定义

const mongoose = require('mongoose');

const streakSchema = new mongoose.Schema({
  _id: {
    type: mongoose.Types.ObjectId,
    ref: "User",
  },
  streaks: [{
    date: {
      type: Date,
      required: true
    },
    questionCount: {
      type: Number,
      required: true,
      default: 0
    }
  }]
});

const Streak = mongoose.model('Streak', streakSchema);

实现代码

前置日期处理

MongoDB的Date类型存储精度到毫秒,需要先将当日日期的时分秒清零,避免匹配失败:

// 构造当日零点的日期对象
const today = new Date();
today.setHours(0, 0, 0, 0);
// 要更新的对应用户ID
const targetUserId = mongoose.Types.ObjectId('你的用户ID字符串');
// 本次要累加的题目数量
const incrementCount = 1;

核心更新逻辑

使用Mongoose聚合管道更新,单次数据库请求完成操作,避免并发读写冲突:

await Streak.updateOne(
  { _id: targetUserId },
  [
    {
      $set: {
        streaks: {
          $cond: {
            // 判断streaks数组中是否存在当日记录
            if: { $in: [today, "$streaks.date"] },
            // 存在则累加对应记录的questionCount
            then: {
              $map: {
                input: "$streaks",
                in: {
                  $cond: [
                    { $eq: ["$$this.date", today] },
                    {
                      $mergeObjects: [
                        "$$this",
                        { questionCount: { $add: ["$$this.questionCount", incrementCount] } }
                      ]
                    },
                    "$$this"
                  ]
                }
              }
            },
            // 不存在则新增当日记录
            else: {
              $concatArrays: [
                "$streaks",
                [{ date: today, questionCount: incrementCount }]
              ]
            }
          }
        }
      }
    }
  ],
  // 可选配置:如果对应用户的streak文档不存在则自动创建
  { upsert: true }
);

注意事项

  • 必须清零日期的时分秒,否则不同时间生成的日期对象会因为毫秒数不同无法匹配
  • 聚合管道更新无需先查询再修改,性能更高,同时避免并发场景下的读写冲突
  • 不需要自动创建用户streak文档时,删除upsert: true参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:27:00