Bibek Das
Bibek Das

Reputation: 45

Mongoose unique validation not working. Duplicate entries getting saved

I am working on a NodeJS application where, express is the framework & MongoDB is the database. I am using mongoose plugin for it.

I have a parent model. I have added unique: true to field "mobile". But whenever I add same mobile number, uniqueness validation fails. Nothing happens rather duplicate document gets saved. The required validation works fine but unique validation does not work only in this particular model.

Below is the model parentModel.js

var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
mongoose.set('useCreateIndex', true);
var Schema   = mongoose.Schema;

var parentSchema = new Schema({
    'name' : {
    type: String,
    required: true
  },
    'mobile' : {
    type: Number,
    unique: true,
    required: true
  },
    'password' : {
    type: String,
    select: false
  },
    'address' : {
    type: String,
    required: true
  },
    'notifications' : [{
        'title': {
        type: String,
        required: true
      },
      'body': {
        type: String,
        required: true
      },
      'path': {
        type: String,
        required: true
      },
    }],
    'activities' : [{
        'title': {
        type: String,
        required: true
      },
      'body': {
        type: String,
        required: true
      },
      'date': {
        type: Date,
        required: true
      }
    }],
    'isVerified' : {
        type: Boolean,
    default: false
    }
},
{
    timestamps: true
});

parentSchema.pre('save', function (next) {
  var parent = this;
  if (this.isNew) {
    var randomstring = Math.random().toString(36).slice(-8);
    bcrypt.genSalt(10, function (err, salt) {
      if (err) {
        return next(err);
      }
      bcrypt.hash(randomstring, salt, null, function (err, hash) {
        if (err) {
          return next(err);
        }
        parent.password = hash;
        next();
      });
    });
  } 
  else if (this.isModified('password')) {
    bcrypt.genSalt(10, function (err, salt) {
      if (err) {
        return next(err);
      }
      bcrypt.hash(parent.password, salt, null, function (err, hash) {
        if (err) {
          return next(err);
        }
        parent.password = hash;
        next();
      });
    });
  }
  else {
    return next();
  }
});

parentSchema.methods.comparePassword = function (passw, cb) {
  console.log(passw)
    bcrypt.compare(passw, this.password, function (err, isMatch) {
        if (err) {
            return cb(err);
        }
        cb(null, isMatch);
    });
};

module.exports = mongoose.model('parent', parentSchema);

Below is the controller parentController.js

create: function (req, res) {
        var parent = new parentModel({
            name : req.body.name,
            mobile : req.body.mobile,
            address : req.body.address

        });

        parent.save(function (err, parent) {
            if (err) {
                return res.status(500).json({
                    message: 'Error when creating parent',
                    error: err
                });
            }
            return res.status(201).json(parent);
        });
    }

Upvotes: 2

Views: 1326

Answers (1)

SuleymanSah
SuleymanSah

Reputation: 17858

Use the following code to check if mongoose could able to create index:


const Parent = mongoose.model('parent', parentSchema);

Parent.on('index', function(err) { 

  if (err) {
    console.log("Could not create index: ", err)
  } else {
    console.log("Index created")
  }

});

module.exports = Parent;

If it gives error, you can create index on MongoDB side.

db.parents.createIndex( { "mobile": 1 }, { unique: true } );

In the docs it says:

In a production environment, you should create your indexes using the MongoDB shell rather than relying on mongoose to do it for you. The unique option for schemas is convenient for development and documentation, but mongoose is not an index management solution.

Upvotes: 1

Related Questions