Mongoose - 模式对象的异步验证

时间:2022-01-31 17:12:31

I am trying to determine how to do asynchronous validation for a Mongoose schema - specifically in this case the username. TMK, to ensure that the username is unique, we have to manually query the database to see if the same username already exists. This is an asynchronous query. However the methodology of having a 'validate:' property for each schema item, seems to ask for a synchronous validation function. In other words, this line:

我正在尝试确定如何对Mongoose模式进行异步验证 - 特别是在这种情况下是用户名。 TMK,为了确保用户名是唯一的,我们必须手动查询数据库以查看是否已存在相同的用户名。这是一个异步查询。但是,为每个模式项设置'validate:'属性的方法似乎要求同步验证功能。换句话说,这一行:

validate: [validation.usernameValidator, 'not a valid username']

验证:[validation.usernameValidator,'不是有效的用户名']

seems to require that usernameValidator be synchronous, and the problem is I need it to be async, for the reason aforementioned.

似乎要求usernameValidator是同步的,问题是我需要它是异步的,原因如上所述。

So, I have a Mongoose schema for a User like so:

所以,我有一个用户的Mongoose模式,如下所示:

   var validation = {

        usernameValidator: function (candidate) {
            return true;
        },
        passwordValidator: function (candidate) {
            return true;
        }
    };


    userSchema = mongoose.Schema({

        username: {
            type: String,
            isUnique: true,
            required: true,
            validate: [validation.usernameValidator, 'not a valid username']
        },
        passwordHash: {
            type: String,
            required: true,
            validate: [validation.passwordValidator, 'not a valid password']
        },
        email: {
            type: String,
            isUnique: true,
            required: true,
            validate: [validation.emailValidator, 'not a valid email address']
        }
    });

    userSchema.pre('save', function (next) {

        var self = this;
        if (!self.isModified('passwordHash')) {
            return next();
        }

        bcrypt.hash(self.passwordPreHash, SALT_WORK_FACTOR, function (err, hash) {
            if (err) {
                return next(err);
            }
            else if(hash == null){
                return next(new Error('null/undefined hash'));
            }
            else {
                self.passwordHash = hash;
                next();
            }
        });
    });


//is the following function my best bet?
      userSchema.path('username').validate(function (value, respond){                                                                                           
    this.findOne({ username: value }, function (err, user){                                                                                                
            if(user)                                                                          respond(false);                                                                                                                         
       });                                                                                                                                                  
}, 'This username has been already registered');

is my only option to leave out the validation.usernameValidator methodology, and validate username with userSchema.path('username').validate..?

是我唯一的选择,省略validation.usernameValidator方法,并使用userSchema.path('username')验证用户名。验证..?

1 个解决方案

#1


2  

Mongoose should handle this provided that you specify unique: true on that field.

只要在该字段上指定unique:true,Mongoose就应该处理此问题。

For example

userSchema = mongoose.Schema({

    username: {
        type: String,
        unique: true,
        required: true
    },
    passwordHash: {
        type: String,
        required: true
    },
    email: {
        type: String,
        unique: true,
        required: true
    }
});

ADDITION:

Mongoose will declare a unique index provided that you specify such in your schema(as done in example above). This prevents having to query into mongodb to see if another document has a field of the same value. You can read about it here.

Mongoose将声明一个唯一索引,前提是您在模式中指定了这样的索引(如上例所示)。这可以防止必须查询到mongodb以查看另一个文档是否具有相同值的字段。你可以在这里读到它。

You can read more about Unique Indexes for mongodb here, if you'd like to learn more about their behaviour.

如果您想了解有关他们行为的更多信息,可以在此处阅读有关mongodb的唯一索引的更多信息。

Note: A validation error will not be throw if a non-unique value is provided. See the mongoose docs for more info on this.

注意:如果提供了非唯一值,则不会抛出验证错误。有关详细信息,请参阅mongoose文档。

#1


2  

Mongoose should handle this provided that you specify unique: true on that field.

只要在该字段上指定unique:true,Mongoose就应该处理此问题。

For example

userSchema = mongoose.Schema({

    username: {
        type: String,
        unique: true,
        required: true
    },
    passwordHash: {
        type: String,
        required: true
    },
    email: {
        type: String,
        unique: true,
        required: true
    }
});

ADDITION:

Mongoose will declare a unique index provided that you specify such in your schema(as done in example above). This prevents having to query into mongodb to see if another document has a field of the same value. You can read about it here.

Mongoose将声明一个唯一索引,前提是您在模式中指定了这样的索引(如上例所示)。这可以防止必须查询到mongodb以查看另一个文档是否具有相同值的字段。你可以在这里读到它。

You can read more about Unique Indexes for mongodb here, if you'd like to learn more about their behaviour.

如果您想了解有关他们行为的更多信息,可以在此处阅读有关mongodb的唯一索引的更多信息。

Note: A validation error will not be throw if a non-unique value is provided. See the mongoose docs for more info on this.

注意:如果提供了非唯一值,则不会抛出验证错误。有关详细信息,请参阅mongoose文档。