2015-08-07 2 views
1

Учитывая коллекцию locations, состоящую из ~ 20000000 документов с 3-мя свойствами:Как я могу запросить коллекцию MongoDB как по географическому пространственному индексу, так и по текстовому индексу?

{ 
    _id, 
    name, // string 
    geo // coordinate pair, e.g. [-90.123456, 30.123456] 
} 

и индексом name: 1 и настройки индекса гео таким образом:

{ 
    "geo" : "2dsphere" 
}, 
{ 
    "v" : 1, 
    "name" : "geo_2dsphere", 
    "ns" : "db.locations", 
    "min" : "-180.0", 
    "max" : "180.0", 
    "w" : 1.0, 
    "2dsphereIndexVersion" : 2 
} 

Как я могу performantly запрос к этой коллекции как по индексу geo_2dsphere, так и по индексу name?

Когда я запускаю запрос $box только для геоинформации, для возврата 50 результатов требуется более 20 секунд. Когда я включаю поиск против свойства name, он идет еще дальше.

Если я бег $near запроса, то все может выполнять очень быстро, но иногда запросы, кажется (очень случайным образом) перейти от ~ 200мса многих секунд. Смотрите в этом примере, где единственным отличием является один дополнительный символ по индексу имя, которое фактически увеличивает время:

200мс:

{name: /^mac/, geo: {$near: {$geometry: {type: "Point", coordinates: [ -90.123456, 30.123456 ]}, $maxDistance: 20000}}} 

18,000ms:

{name: /^macy/, geo: {$near: {$geometry: {type: "Point", coordinates: [ -90.123456, 30.123456 ]}, $maxDistance: 20000}}} 

Я не могу понять, почему более конкретный с индексом замедляет так много. Когда я уточню фразы, я должен резко уменьшить $maxDistance примерно на 7000 метров, прежде чем запрос вернется в любое разумное время.

Есть ли лучшая настройка, которую я должен здесь делать?

+1

Вы не можете. В оценке запроса есть правило «higlander» (может быть только одно), которое отрицает использование более чем «одного» «специального» индекса в оценке запроса. Таким образом, вы не можете иметь несколько «текстовых» или мулифицированных «геопространственных» или любых комбинаций «текста» и «геопространственного» ** или ** использования каких-либо других в условиях ** '$ или' **, что приводит к множественным выбор индекса. Что касается ваших вариантов времени запроса. «Слишком широкий». Вы должны правильно пробовать, и это означает, что на чистом хосте без каких-либо других операций и «полностью разогрет» (все возможные результаты) в памяти. –

+0

Спасибо Блейкс. Я понимаю, что мои примеры времени слишком широки, и я не имею в виду, что их следует принимать конкретным образом, просто очевидно, что существует нежелательная и разнообразная разница во времени ответа.Полагаю, нам нужно будет полностью изучить другую базу данных. –

+1

Существует также вариант «поймать» здесь, где понятие «поиск по имени» может очень хорошо ** не ** быть тем, что сужает эти данные. Например: '.createIndex ({" name ": 1," geo ":" 2dphere "})' отлично выглядит в принципе. Но если есть «больше» из «macy», чем местоположения вблизи точки «geo», это становится контрпродуктивным. Индексирование - это дизайн «осведомленности о данных», а не только те термины, которые вы используете для запроса. Propellerheads в этом году рассматривали это в сообществах SQL. По этой причине никто не понимает концепции индексирования полностью. –

ответ

0

Как уже было отмечено, мне Blakes Seven, вы не можете осуществлять поиск по нескольким индексам в MongoDB:

Существует «правило горца» (может быть только один) в запросе оценки, отрицает использование более чем «одного» «специального» индекса в оценке запроса. Таким образом, вы не можете иметь несколько «text» или muliple «геопространственный» или любую комбинацию «text» и «geospatial» или использование любых из них в пределах $ или условия, что приводит к выбору нескольких индексов .

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

Смежные вопросы