前言
Mongoose 是 Node.js 下应用最广泛的 MongoDB 驱动,它提供了一系列操作 MongoDB 数据库的 API,极大地方便了 Node.js 开发者的开发工作。在开发中,我们经常需要使用到针对某些文档的更新操作,Mongoose 提供了 update() 与 updateOne() 方法进行更新操作。但是,由于 Mongoose 提供了很多的更新方法,我们在实际开发中可能会遇到一些错误和坑,本文将详细探讨 Mongoose 中使用 update 查询的方式及常见错误,并提供一些指导意义,希望能够对大家有所帮助。
update VS updateOne
在 Mongoose 中,我们可以使用 update() 方法和 updateOne() 方法来更新文档。具体的区别如下:
update
- update(query, update, options, callback)
- 返回 promise
- 按 query 更新符合条件的多条文档,如果找不到文档将无效
// 示例代码 Model.update({ name: 'xxx' }, { $set: { age: 18 }}, { multi: true }, function(err, result) { if (err) handleError(err); console.log(result); });
updateOne
- updateOne(filter, update, options, callback)
- 返回 promise
- 按 filter 更新符合条件的一条文档,不会更新多条文档,如果找不到文档仍然有效
// 示例代码 Model.updateOne({ name: 'xxx' }, { $set: { age: 18 }}, function(err, result) { if (err) handleError(err); console.log(result); });
总结
- update() 可以更新多个文档,用在批量操作的场景中。
- updateOne() 只更新符合条件的第一个文档,用在单一操作场景中。
update 的常见错误
在使用 update() 方法时,我们经常会遇到一些错误,下面来详细探讨一下。
错误一:回调函数被调用的次数过多
使用 update() 方法时,如果不加 options 参数,回调函数将会被触发多次,这是因为 Mongoose 会默认将{ multi: true }传入 options 参数,导致回调函数的触发次数不正确。
// 示例代码 Model.update({ name: 'xxx' }, { $set: { age: 18 }}, function(err, result) { if (err) handleError(err); console.log(result); });
此时,若符合条件的文档有 3 个,则回调函数将会被触发 3 次,造成资源浪费,如何解决呢?我们可以在使用 update() 方法时,手动加入 options 参数使得它们不被默认添加的{ multi: true }覆盖。
// 示例代码 Model.update({ name: 'xxx' }, { $set: { age: 18 }}, { multi: false }, function(err, result) { if (err) handleError(err); console.log(result); });
加入 multi: false 后,回调函数将只会被触发一次,这样可以避免资源的浪费。
错误二:update() 方法无法触发钩子函数
Mongoose 中,我们可以使用 update() 方法来更新文档,并且还支持使用 pre() 和 post() 来触发对应的钩子函数。但是,在 update() 方法中,Mongoose 是直接对数据库进行修改操作,不会触发中间件,如果需要触发 pre() 和 post(),我们需要改用 findByIdAndUpdate()、findOneAndUpdate()、updateOne() 或 replaceOne() 方法,并使用 { runValidators: true } 来进行校验。
// 示例代码 // 触发 pre() 钩子 Model.findByIdAndUpdate(id, update, { runValidators: true }, function(err, result) { if (err) handleError(err); console.log(result); });
错误三:update() 方法无法更新嵌套文档的子属性
当需要更新嵌套文档的子属性时,我们需要使用{$set: {'adress.province':'Guangdong'}}的方式进行更新。但是,在使用 update() 方法时,{$set: {'address.province':'Guangdong'}}无效的情况下,我们应该怎么办呢?我们可以使用 updateOne() 方法,来进行嵌套文档中子属性的更新。
// 示例代码 Model.updateOne({ _id: 1 }, { $set: { 'address.province': 'Guangdong' }}, function(err, result) { if (err) handleError(err); console.log(result); });
结语
通过本文,我们详细学习了 Mongoose 中使用 update 查询的方式及常见错误,并掌握了解决这些错误的方法,相信大家在开发中会更加得心应手。最后提醒大家,在编写代码时一定要结合官方文档和自己的实际工作,将理论知识运用到实际项目中去,才能更好地掌握它们。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64c3c31f83d39b48817b4af5