Ron*_*537 6 mongoose mongodb node.js mongoose-schema
根据猫鼬内置验证器文档,我可以使用条件必填字段:
const schema = mongoose.Schema({
a: {
type: String,
required: function () {
return this.b === 1
}
},
b: {
type: Number,
required: true
}
});
Run Code Online (Sandbox Code Playgroud)
在此模式中,a仅当 propertyb等于时才需要该属性1。
尝试创建新文档按预期工作:
Model.create({ b: 1 }); // throws ValidationError (property a is required)
Run Code Online (Sandbox Code Playgroud)
和
Model.create({ b: 2 }); // creates document
Run Code Online (Sandbox Code Playgroud)
我的问题是尝试更新现有文档并将属性设置b为1因此a应该需要属性。
运行以下代码:
Model.findByIdAndUpdate(model._id, { b: 1 }, { new: true, runValidators: true});
Run Code Online (Sandbox Code Playgroud)
意外更新文档而不会抛出a需要属性的错误。
我的猜测是验证仅针对更新的属性(property b)而不是整个文档运行。
我不确定这是预期的行为还是错误...
我错过了什么吗?有什么方法可以运行整个文档的验证器,而不仅仅是更新的属性,而不必手动获取文档?
在尝试了中间件和验证器但没有成功之后,我可以通过使用transactions(可从MongoDB 4.0和获得Mongoose 5.2.0)来实现此要求
// Create a transaction session
const session = await mongoose.startSession();
session.startTransaction();
// Fetch the model (pass the session)
const model = await Model.findById(modelId).session(session);
// ... update your model here
// Validate the schema
if (model.b === 1 && !model.a) {
throw new mongoose.ValidationError('property a is required');
}
// Save the changes
await model.save();
await session.commitTransaction();
Run Code Online (Sandbox Code Playgroud)
请注意,我没有将 附加session到该save函数,因为它已经通过使用以下方式获取模型而附加find:
如果您使用会话从 findOne() 或 find() 获取 Mongoose 文档,该文档将保留对会话的引用并使用该会话进行 save()。
我发现这种方法的一个问题是MongoDB目前仅支持transactions副本集。可以选择在本地运行它,而无需使用副本集进行开发run-rs
要在 macOS、Linux 或 Windows 上运行本地副本集进行开发,请使用 npm 全局安装 run-rs 并运行 run-rs --version 4.0.0。Run-rs 将为您下载 MongoDB 4.0.0。
有关更多信息,您可以查看Mongoose交易文档和MongoDB 文档
| 归档时间: |
|
| 查看次数: |
2401 次 |
| 最近记录: |