Лучший способ сортировки по нескольким полям в запросе geonear

#mongodb

#mongodb

Вопрос:

В MongoDB я выполняю запрос geonear к коллекции, содержащей ~ 3,5 миллиона объектов, чтобы возвращать результаты с определенной широтой / длиной. Этот запрос отлично выполняется, если у меня есть базовый 2d-индекс объекта:

 db.Listing.ensureIndex( { Coordinates: "2d" } );
  

Однако теперь я также хочу фильтровать по другим полям (цена, тип недвижимости, год постройки, Кровати, ванны и т.д.) В запросе geonear. Когда я добавляю в запрос такие вещи, как цена <= 10000000, запрос начинает замедляться. У меня нет никаких индексов по этим другим полям, поэтому мне интересно, какой наилучший подход с точки зрения производительности.

Я пытался добавлять отдельные индексы для каждого из других полей (всего 11 индексов в коллекции), однако это каждый раз приводило к тайм-ауту запроса, я думаю, потому что коллекция может обрабатывать только такое количество индексов?

 db.Listing.ensureIndex( { Coordinates: "2d" } );
db.Listing.ensureIndex( { Price: 1 } );
db.Listing.ensureIndex( { Beds: 1 } );
db.Listing.ensureIndex( { Baths: 1 } );
etc...
  

Теперь я думаю о том, чтобы иметь только 1 составной индекс в коллекции, вот так:

 db.Listing.ensureIndex( { Coordinates: "2d", Price: 1, PropertyType: 1, YearBuilt: 1, Beds: 1, Baths: 1, HouseSize: 1, LotSize: 1, Stories: 1 } );
  

Это правильный подход или есть способ получше?

Ответ №1:

Да, составной индекс, вероятно, правильный путь. Смотрите http://www.mongodb.org/display/DOCS/Geospatial Indexing#GeospatialIndexing-CompoundIndexes подробнее.

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

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