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

使用Mongoose的findOneAndUpdate时如何仅返回$push新增的数组元素

问题原因与前置修复点

当前写法存在两个问题:

  1. 直接用$push传入数组会把整个数组作为单个内嵌文档插入,必须搭配$each操作符才能批量插入多条记录
  2. findOneAndUpdate默认返回更新后的全量文档,所以会带上所有历史salesDate数据

解决方案1:直接构造返回结果(最推荐,性能最优)

你要插入的新记录本身在本地就有完整数据,只需要提前给每条记录生成mongoose默认的ObjectId,插入完成后直接返回这部分数据即可,不需要从数据库返回的全量数据中截取。该方案不受并发更新影响,不会出现截取到其他请求新增数据的问题,稳定性最高。

const { Types } = require('mongoose');
const salesObj = [{ name: "Doe" }, { name: "Tim" }];
// 提前给新增记录生成_id,和数据库自动生成的规则完全一致
const newSalesRecords = salesObj.map(item => ({
  ...item,
  _id: new Types.ObjectId()
}));

// 执行更新
await Car.findOneAndUpdate(
  { _id: "6179bd464c68a217e895703c" },
  { $push: { "salesInfo.salesDate": { $each: newSalesRecords } } },
  { upsert: false, new: true }
);

// 直接构造要求的返回格式
const response = {
  data: {
    salesInfo: {
      salesDate: newSalesRecords
    }
  }
};

解决方案2:从更新返回的全量数据中截取

如果不想提前生成_id,也可以利用已知的本次插入条数,对返回的数组做截取:

const salesObj = [{ name: "Doe" }, { name: "Tim" }];
const insertCount = salesObj.length;

const fullData = await Car.findOneAndUpdate(
  { _id: "6179bd464c68a217e895703c" },
  { $push: { "salesInfo.salesDate": { $each: salesObj } } },
  {
    upsert: false,
    new: true,
    fields: { _id: 0, "salesInfo.salesDate": 1 }
  }
);

// 截取最后insertCount条,就是本次新增的记录
const response = {
  data: {
    salesInfo: {
      salesDate: fullData.salesInfo.salesDate.slice(-insertCount)
    }
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:36:00