4

I want to create a unique index over two columns where the index should allow multiple null values for the second part of the index. But:

db.model.ensureIndex({userId : 1, name : 1},{unique : true, sparse : true});

Throws a duplicate key exception: E11000 duplicate key error index: devmongo.model.$userId_1_name_1 dup key: { : "-1", : null }. I thought because of the sparse=true option the index should allow this constellation? How can I achieve this? I use MongoDB 2.6.5

3 Answers 3

5

Sparse compound indexes will create an index entry for a document if any of the fields exist, setting the value to null in the index for any fields that do not exist in the document. Put another way: a sparse compound index will only skip a document if all of the index fields are missing from the document.

As of v3.2, partial indexes can be used to accomplish what you're trying to do. You could use:

db.model.ensureIndex({userId : 1, name : 1}, { partialFilterExpression: { name: { $exists: true },  unique: true });

which will only index documents that have a name field.

NB: This index cannot be used by mongo to handle a query by userId as it will not contain all of the documents in the collection. Also, a null in the document is considered a value and a field that has a null value exists.

Sign up to request clarification or add additional context in comments.

Comments

2

The compound index should be considered as a whole one, so unique requires (userId, name) pair must be unique in the collection, and sparse means if both userId and name missed in a document, it is allowed. The error message shows that there are at least two documents whose (userId, name) pairs are equivalent (if a field missed, the value can be considered as null).

3 Comments

Hmm ok, so I updated all userId : "-1" to null, but it is still not possible to create the index: E11000 duplicate key error index: devmongo.model.$userId_1_name_1 dup key: { : null, : null }
@KIC, If you can update the value to null, it means you can remove that field, right? Only remove both fields (userId and name) then sparse works which will tell unique that the document should be out of constraint of unique. So, if you remove all userId fields with will -1, make sure name fields are not duplicate, because if one field exists, another missed one will be considered as null.
in fact sparse only works on nonexistant fields. a null field counts as existing field. this is stupid but I have to live with it. Seems that I have to refactor my data model :-(
0

In my case, it turns out field names are case sensitive.

So creating a compound index on {field1 : 1, field2 : 1} is not the same as {Field1 : 1, Field2 : 1}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.