学习MERN栈遇MongooseError:Query was already executed问题求助
问题:Mongoose查询已执行错误(Query was already executed)
执行MERN栈更新操作时触发错误:
MongooseError: Query was already executed: elders.findOne({ _id: new ObjectId("636caae0e3c24f1df7b4e6b7...
对应的代码片段:
router.put("/updateElders", async (req,res)=>{ const newAge = req.body.newAge const id = req.body.id try{ await EldersModel.findById(id, (error, eldertoUpdate) =>{ eldertoUpdate.age = Number (newAge); eldertoUpdate.save(); }) }catch(err){console.log(err);}
错误原因与修复方案
- 错误根源:同时混用了Mongoose的回调函数风格和async/await异步风格。
findById在传入回调时会立即执行查询,再用await等待这个已经执行过的查询对象,就会触发Mongoose的重复执行报错。 - 修复方案:二选一,要么只用回调,要么只用async/await(推荐后者,代码更简洁易读)
方案1:纯async/await写法(推荐)
router.put("/updateElders", async (req,res)=>{ const newAge = req.body.newAge const id = req.body.id try{ // 用await获取查询结果,无需传入回调 const eldertoUpdate = await EldersModel.findById(id); if (!eldertoUpdate) { return res.status(404).json({ message: "未找到对应记录" }); } eldertoUpdate.age = Number(newAge); await eldertoUpdate.save(); // 保存操作同样需要await确保异步完成 res.status(200).json({ message: "更新成功", data: eldertoUpdate }); } catch(err){ console.log(err); res.status(500).json({ message: "更新失败", error: err.message }); } })
方案2:纯回调写法
router.put("/updateElders", (req,res)=>{ const newAge = req.body.newAge const id = req.body.id EldersModel.findById(id, (error, eldertoUpdate) =>{ if (error) { console.log(error); return res.status(500).json({ message: "查询失败", error: error.message }); } if (!eldertoUpdate) { return res.status(404).json({ message: "未找到对应记录" }); } eldertoUpdate.age = Number(newAge); eldertoUpdate.save((saveErr, savedData) => { if (saveErr) { console.log(saveErr); return res.status(500).json({ message: "保存失败", error: saveErr.message }); } res.status(200).json({ message: "更新成功", data: savedData }); }); }) })
额外优化:用findByIdAndUpdate一步完成更新
可以直接使用Mongoose内置的findByIdAndUpdate方法,简化先查询再保存的两步操作:
router.put("/updateElders", async (req,res)=>{ const newAge = req.body.newAge const id = req.body.id try{ const updatedElder = await EldersModel.findByIdAndUpdate( id, { age: Number(newAge) }, { new: true, runValidators: true } // new:true返回更新后的文档,runValidators启用字段校验 ); if (!updatedElder) { return res.status(404).json({ message: "未找到对应记录" }); } res.status(200).json({ message: "更新成功", data: updatedElder }); } catch(err){ console.log(err); res.status(500).json({ message: "更新失败", error: err.message }); } })
内容的提问来源于stack exchange,提问作者Rust
相关产品推荐
相关产品推荐

