猫鼬条件必填字段验证

罗恩537

根据猫鼬内置的验证器文档,我可以使用条件必填字段:

const schema = mongoose.Schema({
    a: {
        type: String,
        required: function () {
            return this.b === 1
        }
    },
    b: {
        type: Number,
        required: true
    }
});

在此方案中,a仅当propertyb等于时才需要该属性1

尝试创建新文档的工作符合预期:

Model.create({ b: 1 }); // throws ValidationError (property a is required)

Model.create({ b: 2 }); // creates document

我的问题是尝试更新现有文档并将属性设置b1因此a需要属性

运行以下代码:

Model.findByIdAndUpdate(model._id, { b: 1 }, { new: true, runValidators: true});

意外地更新文档,而不会引发a需要该属性的错误

我的猜测是,验证仅针对更新的属性(property b)运行,而不是针对整个文档。

我不确定这是预期的行为还是错误...

我想念什么吗?有什么方法可以运行整个文档的验证程序,而不仅是更新后的属性,而不必之前手动获取文档?

罗恩537

在尝试了中间件和验证器之后,没有任何成功,我可以通过使用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();

请注意,我没有将附加sessionsave函数,因为使用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文档。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章