我正在使用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);
}
});
答案 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
数组中找到包含重复电子邮件的文档。