2014-02-06 1 views
0

, если у меня есть эти документы:индекс MongoDB диапазон найти

{"name": 1, "score": 2} 
{"name": 1, "score": 4} 
{"name": 2, "score": 2} 
{"name": 2, "score": 4} 

если обеспечить индекс:

db.test.ensureIndex({"name":1, "score":1}) 

тогда, когда я пытаюсь найти():

db.test.find({"score": 4}) 

Я использую explain() и обнаружил, что этот запрос не может использовать индекс, и он сканирует все четыре документа.

Интересно, почему он сканирует все документы?

вы знаете, если я ENUM все "имя" «s значение (1 и 2):

db.test.find({"$or":["name":1, "name":2], "score":4}) 

он может использовать индекс, и только отсканированные две документы.

Почему mongodb не может это сделать для меня?

+1

вы не должны использовать $ или когда оба положения имеют такое же поле. Вместо этого используйте {name: {$ in: [1, 2]}}. –

ответ

1

Причина Вашего индекс не используются, потому что $or является исключением оператора, и это означает, что более или менее сканирует все для того, чтобы определить, что не матч.

Что вы действительно хотите использовать, это $in. Это уменьшит совпадение до только тех значений, которые содержатся в наборе.

db.test.find({"$in":["name":1, "name":2], "score":4}) 

Как это включительно, что матч может быть применен к индексу, не делая полную проверку.

0

Общее правило большого пальца: Если у вас есть составной индекс и вы ищете по нему поле, вы также должны указать все поля слева от него в определении индекса.

Вы можете представить составные индексы следующим образом: документы индексируются/сгруппированы по первому полю, а затем внутри этих групп индексируются вторым полем.

Итак, когда вы пытаетесь выполнить поиск по второму полю, не указав первый, mongo придется сканировать весь индекс, поскольку он не может эффективно исключать элементы из перемещения.

db.test.find({"name": {"$in": [1, 2]}, "score": 4}) 

В этом случае он будет смотреть только на имена = 1 и name = 2 записи индекса и искать там счет = 4. Если вы не укажете имя, оно будет сканировать все. Это не очень эффективно.

0

В mongoDB, если в коллекции есть составной индекс (например, в вашей коллекции, составной индекс (имя, оценка)), порядок индексированных полей очень важен. MongoDB может использовать составной индекс только для запросов, которые включают префикс полей индекса. Итак, в вашем случае индекс будет только для запросов, которые включают в себя:
1) поле имени
2) поле имени и оценки.

Для любых других запросов индекс не будет использоваться. Это связано с тем, как mongoDB создает сложные индексы. Документы будут сначала проиндексированы по имени, а затем по полям баллов.Если запрос включает только поле оценки, MongoDB не может использовать индекс для поиска документов.

Ссылка: http://docs.mongodb.org/manual/core/index-compound/#compound-index-prefix