Another
very interesting kind of configuring a filter is setting up a so-called partial filter.
Now in our persons collection, we have persons older than 20, older than 30 and so on,
now let's say in the application you're building, which is an application for calculating what your friends
will get once they retire,
you typically only look for persons older than 60. Having an index on the date of birth age field then
might make sense
but the problem of course is that you have a lot of values in your index that you never actually query
for. Now
your index will still be efficient but it will be unnecessarily big
and of course an index
also eats up size on your disk,
additionally the bigger the index is, well the more performance certain queries will take nonetheless.
So if you know that certain values will not be looked at or only very very rarely and you would be fine
using a collection scan if that happens, you can actually create a partial index where you only add the
values you're regularly going to look at,
so in our case here, contacts,
let's see which indexes we have right now
and I only got the ID, so let's now create a new index with create index of course and let's create that
index on the date of birth age field
but there, still in ascending order
but now with an additional argument here and that argument for me is a partial filter expression. As
a side note,
you can also add this to compound index of course because now here, I will define which field is my interesting
field for narrowing down the set of values I want to add and I will use my dob.age field.
Now you could also use a totally different field by the way,
so if you know my queries which I will run should only return me persons which have a gender of male,
then I could also set this here and now I would only store the ages of males in my index, so I could
set gender male here
and this is a normal query expression for equality, greater than, lower than is also supported, exists is supported
and you find the article in the last lecture which also mentions which other queries or filters are supported
here.
So this equal filter is supported
and now what I would create is an index on age, not on gender but on age but only for elements where
the underlying document is for a male.
So this is what I can do, I could have also used the age here though,
so I could have also narrowed down my age filter,
so this would have been an alternative for example,
now I still have the other index created but this would have been alternative, not filtering for another field
but for the same field, the age and then only store elements greater than 60, so whatever you need.
Now I got the male case and therefore we can query for
dob.age,
let's say greater than 60
and pretty print this and we'll see something interesting.
Here we got a male but here, we have a female,
now how does this fit our partial index?
Well let's explain our results here,
so remove pretty and add dot.
explain in front of find. What we see here is that collection scan was performed and not an index scan
because mongodb saw that yes we were looking for a field that is part of an index but it also
determined that since we say nothing about the gender in our query here, it would be too risky to use
the index for that because the index is a partial index and mongodb as a top priority ensures
that you don't lose any data.
So it does not work in a way of naturally filtering out your result sets,
instead what you have to do to use that index is you also have to filter for the gender here,
so if I set gender male here and I explain that, you see now an index scan was performed with the partial
index. And now you might be asking, ok what's the difference between a partial index and a compound index then
if I have to specify both values here? The difference is that for the partial index, the overall index simply
is smaller,
there really are only the ages of males stored in there,
the female keys are not stored in the index and therefore, the index size is smaller leading to a lower
impact on your hard drive and also your right queries are of course also sped up because if you insert
a new female, that will never have to be added to your index.
So this still makes a lot of sense if you often filter for this combination,
so for the age and then only males,
so then a partial index can make sense if you rarely look for your other result, if you rarely look for
women,
this makes a lot of sense.
Whenever mongodb has the impression that your find request would yield more than what's in
your index,
it will not use that index but if you typically run queries where you are within your index, your filtered
or your partial index,
well then mongodb will take advantage of it
and then you benefit from having a smaller index and having less impact with writes.
So again it depends on the application you're writing and whether you often just need a subset
or whether you typically need to be able to query everything, in which case a partial index won't make
much sense.