近几年来,JavaScript 已成为最流行的编程语言之一。在前端开发中,Mongoose 是广泛使用的一种工具,它是一个模型驱动的对象模型工具,可以帮助你更好地操作 MongoDB 数据库。
其中,Mongoose 中的 “validate” 方法是一个非常有用的特性,在添加、更新文档时可以通过定义的验证规则确保数据的有效性。但是,有些用户在使用该方法时发现,在更新文档时无法工作。那么,如何解决呢?
问题原因
在研究该问题之前,需要了解一下 Mongoose 中 “validate” 方法的工作原理。在 Mongoose 中,当你定义一个模型时,可以通过 Schema 中的 “validate” 方法定义一些验证规则。
例如,我们可以通过下面的代码定义一个 User 模型及一个简单的验证规则:
const userSchema = new mongoose.Schema({ username: { type: String, required: true }, email: { type: String, required: true } }); userSchema.path('email').validate(function(value) { const emailRegex = /^\S+@\S+\.\S+$/; return emailRegex.test(String(value).toLowerCase()); }, 'Invalid email address');
在上面的代码中,我们定义了一个 User 模型,包含了 username 和 email 两个字段。同时,我们还定义了一个 email 验证规则,确保 email 符合正则表达式。
然后,在添加、更新文档时,我们可以使用 validate 方法触发验证规则:
const User = mongoose.model('User', userSchema); const user = new User({ username: 'john.doe', email: 'johndoe@example.com' }); user.save((err) => { if (err) console.error(err); console.log('User saved successfully'); });
在上面的代码中,我们创建了一个 User 实例,并调用 save 方法将其保存到数据库中。在 save 方法中,Mongoose 会触发我们定义的验证规则。
以上代码应该能够正确工作,但是当我们试图更新一个文档时,Mongoose 数据库层级的验证规则并不会被默认挂载到任何更新操作中。也就是说,如果你尝试通过 update 方法更新一个文档,数据库层级的验证规则会被忽略。
解决方案
对于这个问题,我们可以使用 Mongoose 的 pre 与 post 钩子来实现验证规则的触发。通过将验证逻辑放到 pre 钩子中,我们可以在执行任何更新文档前先触发验证逻辑并检查文档是否符合条件。
userSchema.pre('update', function (next) { this.options.runValidators = true; next(); });
在上面的代码中,我们将 pre 钩子附加到 update 方法上,并将 runValidators 选项设置为 true。这样,在执行更新操作时,如果文档不符合验证规则,就会抛出一个错误。
完整代码
const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useUnifiedTopology: true }); const userSchema = new mongoose.Schema({ username: { type: String, required: true }, email: { type: String, required: true } }); userSchema.path('email').validate(function(value) { const emailRegex = /^\S+@\S+\.\S+$/; return emailRegex.test(String(value).toLowerCase()); }, 'Invalid email address'); userSchema.pre('update', function (next) { this.options.runValidators = true; next(); }); const User = mongoose.model('User', userSchema); const user = new User({ username: 'john.doe', email: 'johndoe@example.com' }); user.save((err) => { if (err) console.error(err); console.log('User saved successfully'); }); User.updateOne({ username: 'john.doe' }, { email: 'invalid.email' }, (err, result) => { console.log(err); });
总结
在实际使用 Mongoose 中的 “validate” 方法时,我们需要注意到该方法无法在更新文档时正常工作的问题,但是通过使用 pre 钩子,我们可以轻松地解决这个问题。上面的代码给出了一个完整的示例,供大家参考实践。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b71185add4f0e0fffab357