尽管在Mongoose中将电子邮件设置为唯一,但能够使用相同的电子邮件创建多个用户

时间:2017-10-17 19:14:49

标签: javascript node.js mongodb express mongoose

我正在使用Express,MongoDB和Mongoose编写API。我以某种方式能够使用相同的电子邮件创建多个用户。但是,我不能创建具有相同电子邮件地址的其他用户。我的用户架构中有unique: true电子邮件,但这并没有按预期工作。

这是我的用户架构:

var UserSchema = new Schema({
fullName: { type: String, required: [true, 'Full name is required.'] },
emailAddress: {
    type: String, required: true, unique: true,
    validate: {
        validator: function (value) {
            // check for correct email format
            return /^[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(value)
        },
        message: `Please enter a valid email address!`
    }
},
password: { type: String, required: true }
});

我的用户身份验证方法:

UserSchema.statics.authenticate = function (email, password, callback) {
User.findOne({ emailAddress: email })
    .exec(function (err, user) {
        if (err) {
            return callback(err);
        } else if (!user) {
            var error = new Error('User not found');
            error.status = 401;
            return callback(error);
        }
        bcrypt.compare(password, user.password, function (error, user) {
            if (user) {
                return callback(null, user);
            } else {
                return callback();
            }
        });
    });
}

我的预保存挂钩哈希密码:

UserSchema.pre('save', function (next) {
var user = this;
bcrypt.hash(user.password, 10, function (err, hash) {
    if (err) {
        return next(err);
    }
    user.password = hash;
    next();
});
});

最后,我的用户创建路线:

router.post('/', function (req, res, next) {
if (req.body.fullName &&
    req.body.emailAddress &&
    req.body.password &&
    req.body.confirmPassword) {

    if (req.body.password != req.body.confirmPassword) {
        var err = new Error('Passwords do not match!');
        err.status = 400;
        return next(err);
    }

    // object with form input
    var userData = {
        fullName: req.body.fullName,
        emailAddress: req.body.emailAddress,
        password: req.body.password
    };

    // schema's 'create' method to insert document into Mongo
    User.create(userData, function (error, user) {
        if (error) {
            var err = new Error('Please enter a valid email.');
            err.status = 400;
            return next(err);
        } else {
            // set location header to '/', return no content
            res.status(201);
            res.location('/');
            req.session.userId = user._id;
            return res.json(user);
        }
    });

} else {
    var err = new Error('All fields required.');
    err.status = 400;
    return next(err);
}
});

1 个答案:

答案 0 :(得分:1)

如果字段值已经存储了重复项,则MongoDB不会为字段创建唯一索引。

在您的情况下,emailAddress必须具有已存储在数据库中的重复项。 您可以通过运行代码来检查它

mongoose .model(#modelName) .collection.createIndex( { "inviteCode": 1 });

运行此代码后,您应该能够在控制台中看到错误消息。

或者如果您有重复,可以通过运行以下代码进行检查。如果有重复项,下面将获取文档:

mongoose .model(#modelName).aggregate([{ "$group": { "_id": "$loginStatus", count: { $sum: 1 }, ids: { $push: "$_id" } } },{ $match: { count: { $gt : 1 } }}]);

如果您的EmailAddress已经重复,则无法创建唯一:true。您必须运行第二个查询并找出重复的电子邮件地址。您可以在ids数组中找到包含重复电子邮件的文档。