有没有办法用“不可修改”的设置(如类型、必填等)来设置字段?当你定义一个新的Mongoose模式时?这意味着一旦创建了新文档,此字段就不能更改。
例如,如下所示:
var userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unmodifiable: true
}
})发布于 2019-06-30 23:18:12
从Mongoos5.6.0版本开始,我们可以在模式中使用immutable: true (与前面提到的mongoose-immutable包中的答案完全相同)。典型的用例是时间戳,但在您的例子中,对于username,它是这样的:
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
immutable: true
}
});如果您尝试更新字段,修改将被Mongoose忽略。
比OP要求的更进一步,现在使用Mongoos5.7.0我们可以有条件地设置immutable属性。
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
immutable: doc => doc.role !== 'ADMIN'
},
role: {
type: String,
default: 'USER',
enum: ['USER', 'MODERATOR', 'ADMIN'],
immutable: true
}
});资料来源:What's New in Mongoose 5.6.0: Immutable Properties和What's New in Mongoose 5.7: Conditional Immutability, Faster Document Arrays。
发布于 2018-05-27 01:03:37
在userSchema.pre save中,您只能对Mongoose执行此操作
if (this.isModified('modified query')) {
return next(new Error('Trying to modify restricted data'));
}
return next();发布于 2018-07-31 16:26:18
请注意,文档中明确指出,在使用标识符/名称为update的函数时,不会触发'pre‘中间件:
尽管在使用document.Model.findOne({ name: 'borne' }, function (err, doc) { if (err) .. doc.name = 'jason bourne'; doc.save(callback); })时,会将值强制转换为相应的类型,但以下内容不是
您需要这些功能,请使用传统的方法首先检索update
因此,要么使用上面的mongooseAPI,它可以触发中间件(就像desoares answer中的'pre‘),要么触发您自己的验证器,例如:
const theOneAndOnlyName = 'Master Splinter';
const UserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
default: theOneAndOnlyName
validate: {
validator: value => {
if(value != theOneAndOnlyName) {
return Promise.reject('{{PATH}} do not specify this field, it will be set automatically');
// message can be checked at error.errors['username'].reason
}
return true;
},
message: '{{PATH}} do not specify this field, it will be set automatically'
}
}
});或者总是以{ runValidators: true }的形式使用额外的'options‘参数调用任何更新函数(例如,'findByIdAndUpdate’和friends),例如:
const splinter = new User({ username: undefined });
User.findByIdAndUpdate(splinter._id, { username: 'Shredder' }, { runValidators: true })
.then(() => User.findById(splinter._id))
.then(user => {
assert(user.username === 'Shredder');
done();
})
.catch(error => console.log(error.errors['username'].reason));您还可以以非标准的方式使用验证器函数,例如:
...
validator: function(value) {
if(value != theOneAndOnlyName) {
this.username = theOneAndOnlyName;
}
return true;
}
...这不会抛出“ValidationError”,但会悄悄重写指定的值。只有在使用带有指定验证选项参数的save()或update函数时,它才会这样做。
https://stackoverflow.com/questions/50544198
复制相似问题