How to create multiple unique data points in Mongoose schema? How to create multiple unique data points in Mongoose schema? mongoose mongoose

How to create multiple unique data points in Mongoose schema?


Mongoose Provides you the ability to have unique fields.And it returns the error when these conditions are not matched.

For eg: E11000 duplicate key error index in mongodb mongoose

You can update your code like:

const UserSchema = new mongoose.Schema({ email: {  type: String,  required: true,  unique: true,  trim: true}, username: {  type: String,  required: false,  unique: true,  trim: true}})


The issue you are seeing is due to the fact that you have not created a sparse or partial index for the username field.

Do not do this

// Mongoose Schema Versionconst UserSchema = new mongoose.Schema({ email: {  type: String,  required: true,  unique: true,  trim: true}, username: {  type: String,  required: false,  unique: true,  trim: true}})// Mongo Versiondb.users.createIndex({ email: 1 }, { unique: true });db.users.createIndex({ username: 1}, { unique: true });// Mongoose Verion (Users is a Schema)UserSchema.index({ email: 1 }, { unique: true });UserSchema.index({ username: 1 }, { unique: true });

You will have the following issue:

  1. INSERT {email: 'me@email.com'}
  2. Attempt to INSERT {email: 'you@email.com'} -- FAIL!

In MongoDB you have two records trying to set username to null. Whether they set it explicitly or implicitly (by omitting username) that index will fail to store two null items as they collide. That is why if you set individual indexes for the fields the DB gets stuck until a user completes step one, which allows another user to enter step one and submit a null username, but once again blocks the db. It is possible to solve this with a compound index, however that will cause other issues such as users registering the same email to two usernames.

Do this for MongoDB newer than 3.2

Partial indexes only index the documents in a collection that meet a specified filter expression. By indexing a subset of the documents in a collection, partial indexes have lower storage requirements and reduced performance costs for index creation and maintenance.

// Mongo Versiondb.users.createIndex({ email: 1 }, { unique: true });db.users.createIndex({ username: 1}, { unique: true, partialFilterExpression: { username: { $exists: true } } });// Mongoose Verion (Users is a Schema)UserSchema.index({ email: 1 }, { unique: true });UserSchema.index({ username: 1 }, { unique: true, partialFilterExpression: { username: { $exists: true } } });

Do this instead for MongoDB older than 3.2

Sparse indexes only contain entries for documents that have the indexed field, even if the index field contains a null value. The index skips over any document that is missing the indexed field. The index is “sparse” because it does not include all documents of a collection. By contrast, non-sparse indexes contain all documents in a collection, storing null values for those documents that do not contain the indexed field.

// Mongoose Schema Versionconst UserSchema = new mongoose.Schema({ email: {  type: String,  required: true,  unique: true,  trim: true}, username: {  type: String,  required: false,  unique: true,  sparse: true,  trim: true}})// Mongo Versiondb.users.createIndex({ email: 1 }, { unique: true });db.users.createIndex({ username: 1}, { unique: true, sparse: true });// Mongoose Verion (Users is a Schema)UserSchema.index({ email: 1 }, { unique: true });UserSchema.index({ username: 1 }, { unique: true, sparse: true });

Changed in version 3.2: Starting in MongoDB 3.2, MongoDB provides the option to create partial indexes. Partial indexes offer a superset of the functionality of sparse indexes. If you are using MongoDB 3.2 or later, partial indexes should be preferred over sparse indexes.