One interesting variation or use case of the partial index can be seen in conjunction with a unique
index. For this, I will have to create a little demo here, a short example
and I will create a new collection for that, I'll name it users and there I'll insert many documents, two to be precise.
The first document is a user with name Max and an email of max@test.com,
the second document is a user with name Manu and no e-mail,
so just that.
So I have two documents in there and they don't both have the e-mail field, only Max has it.
Now what I can try is I can create an index on users, create index and let's say I want to index my
email field here,
so if I index e-mail in ascending order,
this works, nice.
Now let's drop that index, drop index, e-mail one because what I now want to do is I want to add this index
as a unique index, so unique
true, whoops not here though
but in the second argument to the create index function here, unique true, this also works.
But now let me insert some new document, db users insert one and there, I'll insert Anna
also without an email. And now I get an error, I get a duplicate key error because that non-existing e-mail
for which I have an index is treated as a duplicate key because now I have a no value, so no value stored
twice.
So that is an interesting behavior but some behavior you just have to be aware of, mongodb treats
nonexisting values still as values in your index, so as a not there value
you could say, as a null value and therefore if you have two documents with no value for an indexed field
and that index is unique, you will get this error.
Now if you have that use case and you know yeah but I want to be able to turn this into a unique index
and it's ok if some people don't have an e-mail address, if that is what you want to do, then you have
to create the index a bit differently.
So here I dropped it
and now let me recreate that index and not just set unique to true but you can also add a partial filter
expression now and add a filter for the email field and simply say exists
true, so this filter simply says I only want to add elements into my index where the email field exists
and this will avoid the case of having a clash with unique. If I run this, it works,
if I now try to insert Anna without an email,
this also works.
So now in users, we do have our free users and only one of them has a e-mail,
if I were to try to add Anna with the same email I already have in there,
so with max@test.com, then it would fail because this is indexed, all fields where the e-mail exists
are indexed.
I just used the combination of unique and partial filter expression to not index fields where no value
or where the entire field does not exist
and this allows me to still use unique on that field.