首页 文章

Mongoose:如何防止mongodb在数据库中保存重复的电子邮件记录

提问于
浏览
2

我想让密钥电子邮件在该集合中独一无二,但我无法使其正常工作,这是我的服务器代码 .

// Create a schema
var userSchema = new mongoose.Schema({
    email: { type: String, required: true},
    password: String
});

var userModel = mongoose.model("user", userSchema);

router.post('/postuser', (req, res) => {
    console.log('Requested data to server: ' + JSON.stringify(req.body._user));
var user = new userModel({
    email: req.body._user.email,
    password: req.body._user.password
});
// user.isNew = false;
user.save((err, data) => {
    console.log('Analyzing Data...');
    if(data) {
        console.log('Your data has been successfully saved.');
        res.json(data);
}
else {
  console.log('Something went wrong while saving data.');
  console.log(err);
  res.send(err);
}

})
});

注意:我也尝试 email: { type: String, required: true, unique: true} 但它不工作并显示以下错误 .

name:'MongoError',消息:'E11000重复键错误集合:hutreservationsystem.users索引:_Email_1 dup key:{:null}',driver:true,代码:11000,index:0,errmsg:'E11000重复键错误集合:hutreservationsystem.users index:_Email_1 dup key:{:null}',getOperation:[Function],toJSON:[Function],toString:[Function]}

3 回答

  • 3

    Async Custom Validator

    var userSchema = new mongoose.Schema({
        password: String,
        email: {
            type: String,
            lowercase: true,
            required: true,
            validate: {
                isAsync: true,
                validator: function(value, isValid) {
                    const self = this;
                    return self.constructor.findOne({ email: value })
                    .exec(function(err, user){
                        if(err){
                            throw err;
                        }
                        else if(user) {
                            if(self.id === user.id) {  // if finding and saving then it's valid even for existing email
                                return isValid(true);
                            }
                            return isValid(false);  
                        }
                        else{
                            return isValid(true);
                        }
    
                    })
                },
                message:  'The email address is already taken!'
            },
        }
    });
    

    您可能希望将验证程序代码更改为es6 .

  • 1

    我实现了以下代码以查看是否有任何错误:

    var mongoose = require('mongoose');
    var bodyParser = require('body-parser');
    var express = require('express');
    var http = require('http');
    
    var app = express();
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    
    var Schema = mongoose.Schema;
    
    mongoose.connect('mongodb://localhost/test');
    
    // Create a schema
    var userSchema = new mongoose.Schema({
        email: { type: String, required: true, unique: true},
        password: String
    });
    
    var userModel = mongoose.model("user", userSchema);
    
    app.post('/postuser', (req, res) => {
      console.log('Requested data to server: ' + JSON.stringify(req.body._user));
      var user = new userModel({
          email: req.body._user.email,
          password: req.body._user.password
      });
      // user.isNew = false;
      user.save((err, data) => {
          console.log('Analyzing Data...');
          if(data) {
              console.log('Your data has been successfully saved.');
              res.json(data);
          }
          else {
            console.log('Something went wrong while saving data.');
            console.log(err);
            res.send(err);
          }
      })
    });
    
    http.createServer(app).listen(3000, function(){
      console.log('Express server listening on port 3000');
    });
    

    我确保在我的本地MongoDB数据库中没有 users 名称的集合 . 此外,我使用Postman在 http://localhost:3000 向我的服务器发送API请求 . 似乎没有问题,因为我继续添加具有不同电子邮件值的用户 . 当我输入具有重复值的电子邮件时,我只收到以下错误

    {
      "code": 11000,
      "index": 0,
      "errmsg": "E11000 duplicate key error collection: test.users index: email_1 dup key: { : \"hot@mail.com\" }",
      "op": {
        "email": "hot@mail.com",
        "password": "1234567",
        "_id": "5919a3428c13271f6f6eab0f",
        "__v": 0
      }
    }
    

    这些是我发送的JSON请求:

    {"_user": {"email": "hot@mail.com", "password": "1234"}}
    {"_user": {"email": "sammy@mail.com", "password": "1234"}}
    {"_user": {"email": "tommy@mail.com", "password": "1234"}}
    {"_user": {"email": "tommy@mail.ae", "password": "1234567"}}
    {"_user": {"email": "hot@mail.com", "password": "1234567"}}
    

    上面提到的错误是在最后一次请求时发回的,因为重复了电子邮件 hot@mail.com . 如果您查看链接http://mongoosejs.com/docs/api.html#schematype_SchemaType-unique,则'll see that the E11000 error is only sent when the email entered is not unique. Moreover, your email can' t为空字符串或不存在,因为它违反了必需的属性 .

  • 0

    A short answer using this tool mongoose-unique-validator

    npm install --save mongoose-unique-validator
    

    在你的模型中

    var mongoose = require('mongoose')
    var uniqueValidator = require('mongoose-unique-validator')
    var userSchema = new mongoose.Schema({
        email: { type: String, required: true, unique: true},
        password: String
    });
    
    userSchema.plugin(uniqueValidator)
    var userModel = mongoose.model("user", userSchema);
    

    That's it! (Notice unique: true)

    现在,您的收藏中没有电子邮件重复 .

    奖金! :你可以访问错误

    .catch(err => console.log(err))
    

    所以在你的例子中

    // user.isNew = false;
    user.save((err, data) => {
        console.log('Analyzing Data...');
        if(data) {
            console.log('Your data has been successfully saved.');
            res.json(data);
    }
    else {
      console.log('Something went wrong while saving data.');
      console.log(err);
      res.send(err);
    }
    

    访问错误>>所以你可以res.send(err.message)>>'验证失败'

    {
        message: 'Validation failed',
        name: 'ValidationError',
        errors: {
            email: {
                message: 'Error, expected `email` to be unique. Value: `example@gmail.com`',
                name: 'ValidatorError',
                kind: 'unique',
                path: 'email',
                value: 'example@gmail.com'
            }
        }
        }
    

相关问题