Есть веская причина, по которой ваш индекс не может быть использован для вашего запроса, и я также думаю, что есть некоторые проблемы с самим запросом. Причина, по которой он не попадает в индекс, заключается в том, что между прочим вложенный $ или оператор, но я думаю, что вашей настоящей проблемой является отсутствие понимания всех операторов, доступных вам в MongoDB:
Прежде всего, ваш вложенный $ или проверить, является ли состояние "ca" или "ok", необязательным и (поскольку это главная причина, по которой вы не попали в индекс) можно заменить на state:{$in:["ca", "ok"]}
который делает то же самое. Теперь ваш запрос:
db.foo.find( {
"$or": [
{
"MODIFIED": {
"$gt": {
"sec": 1321419600,
"usec": 0
}
}
},
{
state:{$in:["ca", "ok"]}
}
],
"$and": [
{"fail": {"$ne": 1}},
{"generated": {"$exists": false}}
]
}).explain();
И это поразит ваш индекс. Ваша вторая проблема заключается в том, что $ и $ верхнего уровня не нужны. Обратите внимание, что AND(OR(A, B), AND(C, D)) = AND(OR(A, B), C, D)
. Этот запрос делает то же самое:
db.foo.find( {
"$or": [
{
"MODIFIED": {
"$gt": {
"sec": 1321419600,
"usec": 0
}
}
},
{
state:{$in:["ca", "ok"]}
}
],
"fail": {"$ne": 1},
"generated": {"$exists": false}
}).explain();
Который все еще попадает в индекс:
{
"clauses" : [
{
"cursor" : "BtreeCursor MODIFIED_-1_state_1_fail_1_generated_1 multi",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"MODIFIED" : [
[
{
"$maxElement" : 1
},
{
"sec" : 1321419600,
"usec" : 0
}
]
],
"state" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"fail" : [
[
{
"$minElement" : 1
},
1
],
[
1,
{
"$maxElement" : 1
}
]
],
"generated" : [
[
null,
null
]
]
}
},
{
"cursor" : "BasicCursor",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
],
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1
}
Надеюсь, это поможет! Кстати, немного более привычно начинать первый ключ в вашем составном индексе с порядка 1, а второй с -1. Обратите внимание, что -1 используется только для определения направления относительно предыдущего поля.