Mongoose中deleteMany与save行为差异及原因问询
问题解答
核心差异:Mongoose操作的执行时机
- Mongoose的静态模型方法(比如
deleteMany、find)返回的是Query对象,它实现了Promise接口,但默认是惰性执行的——只有当你通过await、.then()/.catch()或者.exec()来消费这个Promise时,才会真正向MongoDB发送请求执行操作。 - 而
save()是文档实例方法,调用它的瞬间就会立即触发数据库写入请求,不管你有没有处理它返回的Promise。它的异步行为只是不阻塞后续代码,但请求已经发出去了。
你的代码问题分析
- 直接写
Feedback.deleteMany({});时,只是创建了一个未执行的Query对象,根本没触发删除请求,所以数据库里的旧数据还在。 myFeedback.save()调用后,不管有没有写.then(),插入请求已经发送给MongoDB了,所以新数据能正常保存。- 用
.then(...)时,相当于消费了Promise,触发了Query的执行,所以删除操作生效了。
正确写法(保证删除后再保存)
你的需求是先删旧数据再存新数据,必须保证操作顺序,所以要用await等待异步操作完成:
async function DoitFn(){ await Feedback.deleteMany({}); // 等待删除完成 console.log("Deleted"); } app.post("/Process", async function(req,res) { // 路由处理函数加async await DoitFn(); // 确保删除完成后再执行后续操作 console.log("Post request"); const myFeedback = new Feedback ({ // 用const避免全局变量污染 Id: req.body.count, Rating: req.body.myRating, myView: req.body.myView }); console.log(myFeedback.Rating); console.log(myFeedback.myView); await myFeedback.save(); // 等待保存完成 const result = await Feedback.find(); // 用await替代then,代码更清晰 console.log(result); res.send("处理完成"); // 必须给客户端返回响应,避免请求挂起 })
补充说明
- Mongoose的Query对象设计成惰性执行,是为了支持链式调用(比如
Model.find().where('age').gt(18).limit(10)),让你可以先组装查询条件,最后再执行。 - 即使是
save(),也建议处理它的Promise(用await或then),不然保存失败时无法捕获错误,也无法确认操作完成时机。
内容的提问来源于stack exchange,提问作者user3462318
相关产品推荐
相关产品推荐

