Mongoose可选的minlength验证器?

时间:2016-08-13 21:07:39

标签: node.js mongodb mongoose mongoose-schema

如何使用string的可选minlength字段类型。文档(linked here)没有详细说明这个问题?我一直在努力:

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

我尝试的每个变体都会返回某种错误。

我的目标是仅在提供值时评估minlengthmaxlength

5 个答案:

答案 0 :(得分:1)

我不认为您可以使用内置验证器来完成此操作,但您可以使用自定义验证器:

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) }
});

答案 1 :(得分:1)

简短回答:写一个mongoose插件。

答案很长:

您可以向所需的架构添加额外的属性。您通常会编写一个Mongoose 插件来实际执行某些操作。这方面的一个例子是mongoose-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()));

请注意hide: true字段上的password:属性。该插件会覆盖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
    }
};

答案 2 :(得分:1)

您可以使用内置验证器。

我的目标是仅在提供值后才评估minlengthmaxlength

如果值大于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
},

答案 3 :(得分:0)

我遇到了同样的困境,想要一个可选的String,唯一的最小长度和验证,所以我使用多个验证器来做这个技巧也使用了' pre '保存方法来删除空/ 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();
})

答案 4 :(得分:0)

我认为此任务不需要自定义验证器/插件。

如果不需要该值(required: false),则不提供它(或提供null)将不会触发最小/最大长度验证。 如果要允许空字符串或受最小/最大长度限制的字符串,只需使用match正则表达式对此进行测试,例如: /^$|^.{4, 255}$/,或动态构建new RegExp("^$|^.{" + minLength + "," + maxLength + "}$")

在mongoose 4.7.8上测试