Mongo sparse index is not working as I expected Mongo sparse index is not working as I expected mongoose mongoose

Mongo sparse index is not working as I expected


From the documentation on sparse compound indexes:

Sparse compound indexes that only contain ascending/descending index keys will index a document as long as the document contains at least one of the keys.

What this means in your case is that only when all three components of the compound index are missing from the document, will the document be excluded from the index, and thus exempt from the unique constraint.

So the sparse index you're trying to add would allow multiple docs without any of the three keys, but for all other cases, the combination of all three fields must be unique, with any missing fields getting a value of null.

In your example docs, they both would look like the following from the perspective of the unique index:

{    "_type" : "veridianDynamics",    "model" : "sierra",    "model_unique : null}

And thus, not unique.

FYI, there are exceptions to this rule where the existence of a geospatial or text index in your compound, sparse index changes the rules to only consider that specially indexed field when determining whether to include the document in the index.


According to the unique index documentation for missing fields

Unique Index and Missing Field

If a document does not have a value for a field, the index entry for that item will be null in any index that includes it. Thus, in many situations you will want to combine the unique constraint with the sparse option. Sparse indexes skip over any document that is missing the indexed field, rather than storing null for the index entry. Since unique indexes cannot have duplicate values for a field, without the sparse option, MongoDB will reject the second document and all subsequent documents without the indexed field. Consider the following prototype.

Therefore, it seems legitimate to think that this will also work on compound indexes.

This was reported as a bug on jira.

MongoDB developers decided not to include this functionality and closed the request

It makes more sense to exclude documents from the index if ALL fields in the index are missing. Compound indexes also serve queries on the first, first+second, etc fields in the index, and so an index on a,b,c should be able to find all the documents where a=1, not only the ones where b and/or c also have values. This is more intuitive, and should be the default behavior.

Although some suggestions were made in an effort to define a proper semantics to differentiate the two possible cases

{sparse : true, sparseIfAnyValueMissing : true}

It could be useful not only for what I describe in the question, but also for document inheritance and support partial indexing

I have the situation where one of my columns is null when I first create it, but may get set to an ID later. And when it's set to an ID it needs to be unique with another column.

Unfortunately I can't enforce this using a unique index because it will fail since many rows may have null in one of the columns. If I were using a regular RDBMS with a sparse unique multi-column index, this would work fine. Unfortunately Mongo has chosen to work in a different way from all of the RDBMS' out there and cannot support this scenario.

Given that partial indexes are not a quick thing to add and don't seem like they will be added anytime soon, why is this issue closed? Please reopen and consider implementing this issue.

Unfortunately, it is not possible yet (I hope it will be at some point)