Mongoose 可选的最小长度验证器?

G. *_*ard 3 mongoose mongodb node.js mongoose-schema

我怎样才能有一个string带有minlength. 文档(链接在这里)没有详细介绍这一点?我已经试了:

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

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

我的目标是评估minlength并且maxlength 仅当已提供该值时。

rob*_*lep 5

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

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) }
});
Run Code Online (Sandbox Code Playgroud)


Fre*_*key 5

简短的回答:编写一个猫鼬插件。

长答案:

您可以向所需的模式添加额外的属性。您通常会编写一个 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()));
Run Code Online (Sandbox Code Playgroud)

请注意字段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;
  };
}
Run Code Online (Sandbox Code Playgroud)

我的观点是...

...如果您编写一个猫鼬插件(例如,可能是“MinLengthPlugin”),您可以在所有模式上重用它,而无需编写任何额外的代码。在插件中,您可以使用以下内容覆盖功能:

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

    schema.pre('save', myCustomPreSaveHandler);

    var myCustomPreSaveHandler = function() {
       // your logic here
    }
};
Run Code Online (Sandbox Code Playgroud)