Я хотел бы реализовать предложения автозаполнения для регионов, близких к пользователю. Таким образом, для пользователя, находящегося в Сан-Франциско, который входит на Юнион-сквер, он может предложить Юнион-сквер, Сан-Франциско, а затем Юнион-сквер, Нью-Йорк. Это поддерживается таблицей регионов, которая включает имя, центр тяжести и геометрию. Размер таблицы будет около 500 тыс. записей со стандартным (лексическим) индексом по имени и индексом 2dsphere по центроиду. Как мне реализовать это производительным способом?
Используя приведенный ниже запрос, MongoDB, похоже, всегда использует геопространственный индекс, в результате чего время работы составляет 1 с.
{
"name": {
"$regex": "^Union Sq"
},
"centroid": {
"$near": {
"$geometry": { "type": "Point", "coordinates": [-122.39986, 37.75716] }
}
}
}
Если я ограничу результаты радиусом 100 миль, используя $maxDistance, производительность значительно возрастет, но тогда мне понадобится система для создания вторичного неэффективного запроса с использованием $minDistance, если пользователь нацелился на более отдаленный регион. Я полагаю, что мог бы реализовать пользовательский интерфейс так, чтобы вторичные запросы были чисто лексическими, что позволило бы пользователю в конечном итоге находить удаленные регионы после того, как они ввели достаточное количество названий регионов, но близкая сортировка по этим именам была бы идеальной.
Используя приведенный ниже запрос, MongoDB, кажется, работает довольно хорошо, если предложения близки, но когда ему нужно извлекать данные из других регионов, чтобы удовлетворить ограничение, производительность несколько снижается.
regions = await Region.aggregate([
{
$geoNear: {
near: {
type: "Point", coordinates: [-122.39986, 37.75716]
},
key: "centroid",
distanceField: "dist.calculated",
query: {
name: { $regex: '^Union Sq' }
}
}
},
{ $limit: 5 }
]);
Есть лучший способ сделать это? Второстепенные вопросы включают:
- Можно ли заставить MongoDB сначала использовать лексический индекс, а затем сортировать эти результаты географически? MongoDB, кажется, всегда использует геоиндекс, независимо от того, что в первом запросе выше.
- Это, конечно, не критично, но в идеале я хотел бы использовать сортировку с использованием фактической геометрии вместо центроида для более точных результатов... Можно ли это сделать производительным способом?