compound index
{
A: 1,
B: 1
}
In this query, the compound index is not used:
db.user.aggregate([
{ $match: {
B: { $gt: 100 }
} },
{
$sort: {
A: 1
}
},
{
$limit: 1000
}
])
I need do this in order to get it to use the index:
db.user.aggregate([
{ $match: {
A: { $exists: true }
B: { $gt: 100 }
} },
{
$sort: {
A: 1
}
},
{
$limit: 1000
}
])
Adding A: { $exists: true }
is unnecessary because all documents will have this field. I thought that mongodb was smart enough to use an index to sort?
2
Answers
The order of the index fields matter. Indexes are read left to right.
Taken from MongoDB compound index documentation on field order.
$sort
will use the index if is used in the first stage, or if the$sort
stage is only preceded by a$match
stage (documentation).Creating a new index with the following order should fix your problem:
This is of course assuming that your index is not already sorted correctly.
The claim as written seems incorrect or incomplete. When I attempt to reproduce this on version
6.0.1
I see the index being used* as opposed to a collection scan:We can similarly see the index used in this mongoplayground demonstration.
So more specific details about your situation would be required in order to advise further on the question as written. Is collation involved perhaps? But the general answer to your question is that MongoDB can (and does) use the index in the situation that was described which aligns with the documentation referenced in the other answerv
*Notably the index is not used as efficiently as it could be, and so it is probably separately a good idea to include the
$exists
clause to improve performance anyway. It just shouldn’t strictly be required in order to get the index to be used in the first place.