Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb unique sparse index

I have created a sparse and unique index on my mongodb collection.

var Account = new Schema({
                email: { type: String, index: {unique: true, sparse: true} },
                        ....

It has been created correctly:

{ "ns" : "MyDB.accounts", "key" : { "email" : 1 }, "name" : "email_1", "unique" : true, "sparse" : true, "background" : true, "safe" : null }

But if I insert a second document with a key not set I receive this error:

{ [MongoError: E11000 duplicate key error index: MyDB.accounts.$email_1  dup key: { : null }]
  name: 'MongoError',
  err: 'E11000 duplicate key error index: MyDB.accounts.$email_1  dup key: { : null }',
  code: 11000,
  n: 0,
  ok: 1 }

Any hints?

like image 922
Michele Spina Avatar asked Jun 15 '13 15:06

Michele Spina


People also ask

What is sparse index in MongoDB?

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.

Are MongoDB indexes unique?

By default, MongoDB creates a unique index on the _id field during the creation of a collection.

What is a unique index?

Unique indexes are indexes that help maintain data integrity by ensuring that no rows of data in a table have identical key values. When you create a unique index for an existing table with data, values in the columns or expressions that comprise the index key are checked for uniqueness.

What is the difference between dense index and sparse index?

Dense Index: It has index entries for every search key value (and hence every record) in the database file. The dense index can be built on order as well as unordered fields of the database files. Sparse Index: It has index entries for only some of the search key values/records in the database file.


1 Answers

I just had this issue too. I wanted a value to either be null or be unique. So, I set both the unique and the sparse flags:

var UserSchema = new Schema({
  // ...
  email: {type: String, default: null, trim: true, unique: true, sparse: true},
  // ...
});

And, I made sure that the database had actually created the index correctly with db.users.getIndexes();

{
  "v" : 1,
  "key" : {
    "email" : 1
  },
  "unique" : true,
  "ns" : "test.users",
  "name" : "email_1",
  "sparse" : true,
  "background" : true,
  "safe" : null
},

(So, this is not the same as the issue here: mongo _id field duplicate key error)

My mistake was setting the default value to null. In some sense, Mongoose counts an explicit null as a value that must be unique. If the field is never defined (or undefined) then it is not enforced to be unique.

email: {type: String, trim: true, unique: true, sparse: true},

So, if you are having this issue too, make sure you're not setting default values, and make sure you're not setting the values to null anywhere else in your code either. Instead, if you need to set it explicitly, set it to undefined (or a unique value).

like image 60
Rabbits Avatar answered Oct 01 '22 12:10

Rabbits