MongoDB findOneAndUpdate如何区分新增与更新并返回对应提示
实现MongoDB findOneAndUpdate区分新增/更新并返回对应提示
完全可以实现,核心是获取操作前的旧记录,结合更新结果判断操作类型,返回对应提示。以下是具体实现方案:
方案一:先查询旧记录再执行更新(直观易维护)
这种方式先查询员工的现有美国地区门店记录,再执行更新/新增操作,通过旧记录是否存在区分操作类型,同时能判断门店是否真的发生变化:
// 1. 查询员工当前的美国地区门店记录 const oldEmployeeStore = await this.employeeStoreModel.findOne({ employee: employeeRecord._id, location: "America" }); // 2. 执行更新或新增操作 const updatedEmployeeStore = await this.employeeStoreModel.findOneAndUpdate( { employee: employeeRecord._id, location: "America" }, { employee: employeeRecord._id, store: employeeRecord.store, location: "America", }, { new: true, upsert: true } ); // 3. 根据操作类型生成对应提示 let message; if (!oldEmployeeStore) { // 新增记录场景 message = `${updatedEmployeeStore.store} has a new employee - ${updatedEmployeeStore.employee}`; } else { if (oldEmployeeStore.store !== updatedEmployeeStore.store) { // 门店变更场景 message = `${updatedEmployeeStore.employee} has changed from ${oldEmployeeStore.store} to ${updatedEmployeeStore.store}`; } else { // 无变更场景(可根据业务需求调整或移除) message = `${updatedEmployeeStore.employee} is already assigned to ${updatedEmployeeStore.store}`; } } return message;
方案二:利用findOneAndUpdate原始结果判断(适合高并发场景)
如果系统并发较高,担心查询与更新之间的竞态问题,可以开启rawResult选项获取完整操作元数据,结合upsertedId判断是否为新增:
const updateResult = await this.employeeStoreModel.findOneAndUpdate( { employee: employeeRecord._id, location: "America" }, { employee: employeeRecord._id, store: employeeRecord.store, location: "America", }, { new: false, // 返回旧文档 upsert: true, rawResult: true // 获取完整操作结果对象 } ); let message; const oldRecord = updateResult.value; const newRecord = updateResult.upsertedId ? await this.employeeStoreModel.findById(updateResult.upsertedId) : await this.employeeStoreModel.findOne({ employee: employeeRecord._id, location: "America" }); if (updateResult.upsertedId) { // 新增记录场景 message = `${newRecord.store} has a new employee - ${newRecord.employee}`; } else { if (oldRecord.store !== newRecord.store) { // 门店变更场景 message = `${newRecord.employee} has changed from ${oldRecord.store} to ${newRecord.store}`; } else { message = `${newRecord.employee} is already at ${newRecord.store}`; } } return message;
关键说明
- 方案一代码直观、逻辑清晰,适合大多数业务场景;
- 方案二通过操作元数据避免竞态问题,适配高并发场景;
- 额外判断门店是否真的变化,可避免重复更新相同门店时返回错误提示。
内容的提问来源于stack exchange,提问作者user19238266
相关产品推荐
相关产品推荐

