MongoDB循环回调内保存集合:创建Author后User保存失败如何解决
问题排查与修复方案
核心报错原因
你调用User.find()时使用了.lean()方法,该方法的作用是让mongoose返回纯JS对象而非mongoose文档实例,返回的user对象上没有mongoose内置的save方法,因此触发TypeError: user.save is not a function报错。
额外逻辑隐患
- 使用
forEach循环处理异步操作,执行顺序不可控,无法保证所有用户操作完成后再返回响应 - 循环内部每次执行完操作都调用
res.send,会导致同一个请求多次返回响应,触发服务端报错
修复代码示例
推荐使用async/await改写异步逻辑,去掉.lean()获取带内置方法的文档实例:
try { // 去掉lean(),获取mongoose文档实例 const activeUsers = await User.find({ status: 'active', connect_to: null }) // 用for of循环处理异步操作,保证执行顺序 for (const user of activeUsers) { // 创建作者档案 const newAuthor = await Author.create({ status: 1, name: user.name, from_user: user._id }) // 更新用户关联字段后保存 user.connect_to = newAuthor._id await user.save() } // 所有操作完成后统一返回响应 return res.status(200).send('Accounts have been updated') } catch (err) { return res.status(400).send('There is an issue with your request') }
如果你确实需要保留.lean()来提升查询性能,可以直接调用User模型的更新方法修改对应用户,不需要调用save:
try { const activeUsers = await User.find({ status: 'active', connect_to: null }).lean() for (const user of activeUsers) { const newAuthor = await Author.create({ status: 1, name: user.name, from_user: user._id }) // 直接通过ID更新用户的connect_to字段 await User.findByIdAndUpdate(user._id, { connect_to: newAuthor._id }) } return res.status(200).send('Accounts have been updated') } catch (err) { return res.status(400).send('There is an issue with your request') }
内容的提问来源于stack exchange,提问作者Kien Pham
相关产品推荐
相关产品推荐

