использование сортировки с $ или запретить использование индексов в mongodb? - PullRequest
0 голосов
/ 31 марта 2012

похоже, что использование $ или с сортировкой выполняет полное сканирование таблицы и избегает моих индексов по заголовку и ключевым словам. Как я могу заставить его использовать мои два индекса при использовании $ или запроса?

этот запрос использует как заголовок, так и индекс ключевых слов

db.tasks.find({$or: [{keywords: /^japan/}, {title:/^japan/}]})

при этом выполняется полное сканирование таблицы и используется мой индекс total_-1

db.tasks.find({$or: [{keywords: /^japan/}, {title:/^japan/}]}).sort({total:-1})

в то время как запросы к ключевым словам или заголовку с сортировкой используют индексы для ключевых слов или заголовка соответственно.

db.tasks.find({title:/^japan/}).sort({total:-1})
db.tasks.find({keywords:/^japan/}).sort({total:-1})

1 Ответ

1 голос
/ 31 марта 2012

Сортировка и индексы в Mongo - сложная тема.Mongo также имеет специальную ошибку, которая не позволяет выполнять сортировку без индекса, если у вас слишком много элементов.Так что хорошо, что вы спрашиваете об индексах, потому что неиндексированная сортировка в конечном итоге начнет давать сбой.

В JIRA есть ошибка , которая, кажется, покрывает вашу проблему, однако естьнекоторые дополнительные детали для рассмотрения.

Первое, на что стоит обратить внимание, это ваши последние запросы:

db.tasks.find({title:/^japan/}).sort({total:-1})
db.tasks.find({keywords:/^japan/}).sort({total:-1})

Эти запросы в конечном итоге завершатся неудачно, потому что вы индексируете только на title, а не title/total,Вот скрипт, который продемонстрирует проблему.

> db.foo.ensureIndex({title:1})
> for(var i = 0; i < 100; i++) { db.foo.insert({title: 'japan', total: i}); }
> db.foo.count()
100
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
... uses BTreeCursor title_1
> // Now try with one million items
> for(var i = 0; i < 1000000; i++) { db.foo.insert({title: 'japan', total: i}); }
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
Sat Mar 31 05:57:41 uncaught exception: error: {
        "$err" : "too much data for sort() with no index.  add an index or specify a smaller limit",
        "code" : 10128
}

Так что, если вы планируете запрашивать и сортировать по title и total, тогда вам нужен индекс для обоих, в следующем порядке:

> db.foo.ensureIndex({title:1,total:1})
> db.foo.find({title: 'japan'}).sort({total:-1}).explain()
{
        "cursor" : "BtreeCursor title_1_total_1 reverse",
...

Ошибка JIRA, которую я перечислил выше, относится к следующему:

> db.foo.find({$or: [title:/^japan/, title:/^korea/]}).sort({total:-1})

Ваша ошибка немного отличается, но она столкнется с той же проблемой.Даже если у вас есть оба индекса на title/total и keyword/total, MongoDB не сможет оптимально использовать индексы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...