it-swarm.com.ru

Сортировка по нескольким полям mongoDB

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

Скажи, что я должен сделать запрос

db.col.find({category: A}).sort({updated: -1, rating: -1}).limit(10).explain()

Итак, я создал следующий индекс

db.col.ensureIndex({category: 1, rating: -1, updated: -1})

Работало только оштрафованное сканирование как можно большего количества объектов, то есть 10

Но теперь мне нужно запросить 

db.col.find({category: { $ne: A}}).sort({updated: -1, rating: -1}).limit(10)

Итак, я создал следующий индекс

 db.col.ensureIndex({rating: -1, updated: -1})

но это приводит к сканированию всего документа и когда я создаю 

 db.col.ensureIndex({ updated: -1 ,rating: -1})

Сканирует меньше документов

Я просто хочу попросить прояснить порядок сортировки по нескольким полям и порядок сохранения при этом. Читая документы mongo-DB, становится ясно, что поле, в котором нам нужно выполнить сортировку, должно быть последним полем. Так что это случай, который я предположил в моем запросе $ ne выше. Я делаю что-то не так?

24
Global Warrior

MongoDB оптимизатор запросов работает, пробуя разные планы, чтобы определить, какой подход лучше всего подходит для данного запроса. Выигрышный план для этого шаблона запроса затем кэшируется для следующих ~ 1000 запросов или до тех пор, пока вы не выполните explain().

Чтобы понять, какие планы запросов были рассмотрены, вы должны использовать explain(1) , например:

db.col.find({category:'A'}).sort({updated: -1}).explain(1)

Деталь allPlans покажет все планы, которые были сравнены.

Если вы выполняете запрос, который не очень избирателен (например, если многие записи соответствуют вашим критериям {category: { $ne:'A'}}), MongoDB может быстрее найти результаты, используя BasicCursor (сканирование таблицы), а не сопоставление с индексом.

Порядок полей в query обычно не имеет значения для выбора индекса (есть несколько исключений для запросов диапазона). Порядок полей в sort влияет на выбор индекса. Если ваш критерий sort() не соответствует порядку индекса, данные результатов должны быть повторно отсортированы после использования индекса (в этом случае вы должны увидеть scanAndOrder:true в выводе объяснения).

Также стоит отметить, что MongoDB будет использовать только один индекс на запрос (за исключением $ors).

Так что, если вы пытаетесь оптимизировать запрос:

db.col.find({category:'A'}).sort({updated: -1, rating: -1})

Вы захотите включить все три поля в индекс:

db.col.ensureIndex({category: 1, updated: -1, rating: -1})

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

27
Stennie

Это правда, но у вас есть два уровня упорядочения, так как вы сортируете по составному индексу.

Как вы заметили, когда первое поле индекса совпадает с первым полем сортировки, оно сработало, и индекс был виден. Однако при работе наоборот это не так.

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

1
Sammaye

попробуйте этот код, он сначала отсортирует данные по имени, а затем сохранит «имя» в держателе ключей, он будет сортировать «фильтр» 

 var cursor = db.collection('vc').find({   "name" :   { $in: [ /cpu/, /memo/ ]   }     }, { _id: 0, }).sort( { "name":1  ,  "filter": 1 } );
0
Gajender Singh