猫鼬可选的最小长度验证器?

Mongoose optional minlength validator?

我怎样才能拥有带有 minlength 的可选 string 字段类型。文档 (linked here) 没有对此进行详细说明?我一直在努力:

var schema = mongoose.Schema({
    name: { type: String, required: true, maxlength: 255 },
    nickname: { type: String, minlength: 4, maxlength: 255 }
});

我尝试的每个变体returns 某种类型的错误。

我的目标是评估 minlengthmaxlength 仅当 已提供值时。

我不认为你可以使用内置验证器来做到这一点,但你可以使用自定义验证器:

var optionalWithLength = function(minLength, maxLength) {
  minLength = minLength || 0;
  maxLength = maxLength || Infinity;
  return {
    validator : function(value) {
      if (value === undefined) return true;
      return value.length >= minLength && value.length <= maxLength;
    },
    message : 'Optional field is shorter than the minimum allowed length (' + minLength + ') or larger than the maximum allowed length (' + maxLength + ')'
  }
}

// Example usage:
var schema = mongoose.Schema({
    name    : { type: String, required: true, maxlength: 255 },
    nickname: { type: String, validate: optionalWithLength(4, 255) }
});

简答:写一个 mongoose 插件。

长答案:

您可以根据需要向架构添加额外的属性。您通常会编写一个 Mongoose Plugin 来对它们进行实际操作。这方面的一个例子是 mongoose-hidden 插件,它允许您在转换期间将某些字段定义为 hidden

var userSchema = new mongoose.Schema({
  name: String,
  password: { type: String, hide: true }
});
userSchema.plugin(require('mongoose-hidden'));

var User = mongoose.model('User', userSchema, 'users');
var user = new User({ name: 'Val', password: 'pwd' });
// Prints `{ "name": "Val" }`. No password!
console.log(JSON.stringify(user.toObject()));

请注意 password: 字段中的 hide: true 属性。插件覆盖 toObject() 功能,自定义版本删除查找属性并删除字段。

这是插件的主体。第 4 行检查是否存在 schemaType.options.hide 属性:

function HidePlugin(schema) {
  var toHide = [];
  schema.eachPath(function(pathname, schemaType) {
    if (schemaType.options && schemaType.options.hide) {
      toHide.push(pathname);
    }    
  });
  schema.options.toObject = schema.options.toObject || {};
  schema.options.toObject.transform = function(doc, ret) {
    // Loop over all fields to hide
    toHide.forEach(function(pathname) {
      // Break the path up by dots to find the actual
      // object to delete
      var sp = pathname.split('.');
      var obj = ret;
      for (var i = 0; i < sp.length - 1; ++i) {
        if (!obj) {
          return;
        }
        obj = obj[sp[i]];
      }
      // Delete the actual field
      delete obj[sp[sp.length - 1]];
    });

    return ret;
  };
}

我的观点是...

... 如果您编写一个 mongoose 插件(例如,可能是 "MinLengthPlugin"),您可以在所有模式上重复使用它而无需编写任何额外的代码。在插件中,您 可以 用类似的东西覆盖功能:

module.exports = function MinLenghPlugin (schema, options) {

    schema.pre('save', myCustomPreSaveHandler);

    var myCustomPreSaveHandler = function() {
       // your logic here
    }
};

我 运行 陷入同样的​​困境,想要一个可选的、唯一的、具有最小长度和验证的字符串,所以我使用了多个验证器来完成这个技巧,也使用了 'pre' 删除 empty/null 值的保存方法,因此没有重复项,因为空字符串不是唯一的

var validateUserNameLength = function (username) {
    if (username && username.length !== '') {
        return username.length >= 3;
    }
   return true;
};

var validateUserNameFormat = function (username) {
    if (username && username.length) {
        return username !== 'foo;
    }
    return true;
 }


var validateUserName= [
    { validator: validateUserNameLength , msg: 'short UserName' },
    { validator: validateUserNameFormat , msg: 'No Foo name' }
]; 

var UserSchema= mongoose.Schema({
    userName: {
        type: String,
        lowercase: true,
        trim: true,
        index: {
            unique: true,
            sparse: true
        },
        validate: validateUserName,
        maxlength: [20, 'long UserName']
    },
});

UserSchema.pre('save', function (next) {
   if (this.userName === null || this.userName === '') {
       this.userName = undefined;
   }

   next();
})

我认为此任务不需要自定义 validator/plugin。

如果不需要该值 (required: false),则不提供它(或提供 null)将不会触发 min/max 长度验证。 如果您想允许空字符串或受 min/max 长度限制的字符串,只需使用 match 正则表达式来测试它,例如/^$|^.{4, 255}$/,或者动态构造一个new RegExp("^$|^.{" + minLength + "," + maxLength + "}$")

在猫鼬 4.7.8 上测试

您可以使用内置验证器。

My goal is to evaluate the minlength and maxlength only if the value has been supplied.

如果值大于 12 且值等于 0,则不会生成错误,但如果其中一个条件错误,则会生成验证错误。

enrollment_no: {
    type: String,
    trim: true,
    // minlength: [12, 'Enrollment number must be at least 12 characters long'],
    maxlength: [16, 'Enrollment number is not allowed more than 16'],
    validate: {
        validator: function(val) {
            return val.length >= 12 || val.length === 0
        },
        message: () => `Enrollment number must be at least 12 characters long`
    },
    default: null
},