DEV Community

Cover image for Solved! Mongoose Unique Index Not Working
Emmy Steven
Emmy Steven

Posted on

Solved! Mongoose Unique Index Not Working

I was working on a project for an organisation I volunteer for, I encountered some difficulties in making the email field in my database schema to be unique, below is a sneak peek into my database schema, it's a typical database schema anyway.

import mongoose from 'mongoose'

const { Schema } = mongoose

const value = {
  type: String,
  required: true,
  trim: true,
  unique: false
}

const UserSchema = new Schema({
  fname: value,
  lname: value,
  email: {
    type: String,
    required: true,
    trim: true,
    unique: true
  }
}, {
  timestamps: true,
  get: v => v.toDateString()
})

const User = mongoose.model('User', UserSchema)
export default User
Enter fullscreen mode Exit fullscreen mode

and when I started my server and did my API test using Paw (REST Client like Postman), I found out that I could enter the same email again and again and that was not what I wanted.

I went to Google as usual to seek solution to this abnormality, here are the thing I tried that didn't work:

Restarting MongoDB
and then doing the following:
mongo mydb
db.users.reIndex()

when this one above did no work out, I this one below

UserSchema.index({ username: 1, email: 1 }, { unique: true});

when this one too didn't work, I was also asked to do modify my code with this:

import uniqueValidator from 'mongoose-unique-validator'

// UserSchema = Schema({}) etc...

UserSchema.plugin(uniqueValidator)
Enter fullscreen mode Exit fullscreen mode


javascript

I didn't do this because I felt so uncomfortable using a plugin to enforce a unique constraint on a particular field.

I really don't know why the aforementioned solutions didn't work for me at all. However, I stumbled upon a solution that did the magic, and I think this method is the best approach in my opinion.

I had to do this at the connection level:

'use strict'
import 'dotenv/config'
import db from 'mongoose'

const options = {
  useNewUrlParser: true,
  useCreateIndex: true,
  autoIndex: true, //this is the code I added that solved it all
  keepAlive: true,
  poolSize: 10,
  bufferMaxEntries: 0,
  connectTimeoutMS: 10000,
  socketTimeoutMS: 45000,
  family: 4, // Use IPv4, skip trying IPv6
  useFindAndModify: false,
  useUnifiedTopology: true
}

db.connect(process.env.DB_URI, options)
  .then(() => console.log('> Successfully connected to DB'))
  .catch(err => console.log(err))

// syntactic sugar for { db: db }
export default { db }
Enter fullscreen mode Exit fullscreen mode

what happens when you add

audoIndex: true

is that when you run your code it will create empty collection(s) and the corresponding index(es) which won't happen if you didn't add it.

MongoDB together with Mongoose can be pretty weird

Latest comments (7)

Collapse
 
fahimshahriar profile image
Fahim Shahriar • Edited

Thanks man ❤️
when i use this
family: 4, // Use IPv4, skip trying IPv6
my code works. But didn't understand why?

Collapse
 
vu159951 profile image
tran vu

Just need to add dropDups: true to your schema .

Collapse
 
emmysteven profile image
Emmy Steven

Thanks

Collapse
 
jwandekoken profile image
Julio Wandekoken

Thanks. This worked for me.

Collapse
 
emmysteven profile image
Emmy Steven

Glad it did

Collapse
 
patostickar profile image
patostickar

Don't know how you found out, but huge thanks!

Collapse
 
utkarshsingh99 profile image
Utkarsh Singh

Oh God, thanks for this! 🙏
Please add this to SOF too!