18

For example if I have this schema

var userSchema = mongoose.Schema({
    username: String,
    email: String,
    password: String,
    _todo: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Todo'}]
});

I would like the username to be a unique key that cannot be duplicated by other users. How can I do this?

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Monece Solis
  • 683
  • 2
  • 6
  • 23

2 Answers2

25

You can add a constraint with the unique attribute. This will also add a "unique" index for the field to your collection:

var userSchema = mongoose.Schema({
    username: { type: String, unique: true },
    email: String,
    password: String,
    _todo: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Todo'}]
});
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • 1
    The correct answer is below, especially given "you should create your indexes using the MongoDB shell rather than relying on mongoose to do it for you." – Peter Cheng Jun 04 '19 at 01:25
17

I came across the same issue. But can't be solved by the accepted answer.

For my example is very simple, just make the name unique.

var FoolSchema = Schema({
    name: {
      type: String,
      unique: true,
      index: true,
      required: true
    }
})

I can save the duplicate name every time.

Then I find this link: https://mongoosejs.com/docs/faq.html#unique-doesnt-work

The solution is createIndex from mongoDB, not from mongoose.

  1. start mongo shell mongo, and use yourdbName
  2. run db.foos.getIndexes() (you can't see the "unique" : true, )
  3. db.foos.createIndex( { "name": 1 }, { unique: true } )
  4. try step 2. The results should contains unique.

Hope it could help someone.

EDIT If your foo table collections contain the duplicated names, you might get error on step 3:

{
    "ok" : 0,
    "errmsg" : "E11000 duplicate key error collection: mategoal-dev.categories index: name_1 dup key: { : \"TheName\" }",
    "code" : 11000,
    "codeName" : "DuplicateKey"
}

Then remove all the data or duplicated one(haven't test) first:

db.foos.remove({})

Then try step 3 again.

William Hu
  • 15,423
  • 11
  • 100
  • 121
  • 1
    [Restart mongo](https://stackoverflow.com/questions/5535610/mongoose-unique-index-not-working) makes it work without using the mongo shell solution. At least it works for me. – holydragon Jun 25 '20 at 07:57