Home > Software design >  How to make Mongoose unique key validation to pass if other key is different?
How to make Mongoose unique key validation to pass if other key is different?

Time:08-24

Lets say we have this model :

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    unique: true,
    uniqueCaseInsensitive: true,
    required: true,
  },
  organisation: {
    type: Schema.Types.ObjectId,
    ref: "organisation",
  }
});

const UserModel: mongoose.model("user", userSchema),

and we already have this document in our collection :

{
_id: "62e10be79f7ef6f083ca7827",
username : "John",
organisation : {
    "$oid": "62d08a16bf95e75ccbf23dcc"
  }
}

and we try to store a document with the same username we will get E11000 duplicate key error collection

What if i want this unique validation to be triggered only when organisation is the same as well ?

So it will NOT ALLOW this to be stored :

    const user = new UserModel({
      name: "John",
      organisation: "62d08a16bf95e75ccbf23dcc",
    });
    await user.save();

But it will ALLOW this :

    const user = new UserModel({
      name: "John",
      organisation: "32d08y78bf95i75ccbf56dca",
    });
    await user.save();

CodePudding user response:

You can define compound index on schema level:

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
  },
  organisation: {
    type: Schema.Types.ObjectId,
    ref: "organisation",
  }
});

userSchema.index(
    { name: 1, organisation: 1 }, 
    {unique: true, collation:{locale:"en", strength:2 }}
); 

collation option relaxes strength to 2 to make it case-insensitive

CodePudding user response:

use mongoose-unique-validator package.

const uniqueValidator = require('mongoose-unique-validator');

const userSchema = new mongoose.Schema({
  username: {
    type: String,
    unique: true,
    uniqueCaseInsensitive: true,
    required: true,
  },
  organisation: {
    type: Schema.Types.ObjectId,
    ref: "organisation",
  }
});

userSchema.plugin(uniqueValidator,{ message: 'Error, expected {VALUE} to be unique.' });
const UserModel: mongoose.model("user", userSchema),
  • Related