Учитывая коллекцию 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 метров, прежде чем запрос вернется в любое разумное время.
Есть ли лучшая настройка, которую я должен здесь делать?
Вы не можете. В оценке запроса есть правило «higlander» (может быть только одно), которое отрицает использование более чем «одного» «специального» индекса в оценке запроса. Таким образом, вы не можете иметь несколько «текстовых» или мулифицированных «геопространственных» или любых комбинаций «текста» и «геопространственного» ** или ** использования каких-либо других в условиях ** '$ или' **, что приводит к множественным выбор индекса. Что касается ваших вариантов времени запроса. «Слишком широкий». Вы должны правильно пробовать, и это означает, что на чистом хосте без каких-либо других операций и «полностью разогрет» (все возможные результаты) в памяти. –
Спасибо Блейкс. Я понимаю, что мои примеры времени слишком широки, и я не имею в виду, что их следует принимать конкретным образом, просто очевидно, что существует нежелательная и разнообразная разница во времени ответа.Полагаю, нам нужно будет полностью изучить другую базу данных. –
Существует также вариант «поймать» здесь, где понятие «поиск по имени» может очень хорошо ** не ** быть тем, что сужает эти данные. Например: '.createIndex ({" name ": 1," geo ":" 2dphere "})' отлично выглядит в принципе. Но если есть «больше» из «macy», чем местоположения вблизи точки «geo», это становится контрпродуктивным. Индексирование - это дизайн «осведомленности о данных», а не только те термины, которые вы используете для запроса. Propellerheads в этом году рассматривали это в сообществах SQL. По этой причине никто не понимает концепции индексирования полностью. –