Mongoose - 模式对象

时间:2015-06-26 22:51:20

标签: node.js mongodb asynchronous mongoose

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

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

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

所以,我有一个类似于用户的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');

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

1 个答案:

答案 0 :(得分:2)

如果您在该字段上指定unique: true,Mongoose应处理此问题。

例如

userSchema = mongoose.Schema({

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

<强>此外:

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

如果您想了解有关其行为的更多信息,可以阅读有关mongodb here的唯一索引的详情。

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