#mongodb #indexing #nosql #geospatial
Вопрос:
У меня есть коллекция в MongoDB, где документы имеют такую структуру:
{
"vechicleDetails": {
"location": {
"type": "Point",
"coordinate": [78.00, -40] //longitude, latitude
},
"city": "New Delhi"
},
"searchPriority": 4,
"isLive": true,
"vehicleCondition": "USED",
"dateOfGoingLive": ISODate()
}
Есть также много других полей, но я опустил их, потому что они не имеют отношения к этому вопросу.
У меня есть запрос, который будет выполняться очень часто в этой коллекции:
db.vehicleinventories_latlong.find({ $query: {isLive: false, vehicleCondition: "USED", "vehicleDetails.city": {$in: ["New Delhi", "Delhi", "Gurugram"]}, "vehicleDetails.location": { $nearSphere: { $geometry: { type: "Point", coordinates: [ 77.2, 28.6 ] }, $maxDistance: 100 * 1000 } }}, $orderby: {searchPriority: -1, dateOfGoingLive: -1} })
С помощью этого запроса я пытаюсь получить все документы, которые соответствуют следующим критериям:
- isLive: ложь
- Состояние транспортного средства: «ИСПОЛЬЗУЕТСЯ»
- vehicleDetails.city-одна из этих ценностей: Нью-Дели, Дели, Гуруграм,
- Автомобильные хвосты.местоположение находится в радиусе 100 км от [ 77.2, 28,6 ] (долгота, широта в этом порядке)
Я хочу, чтобы результаты были отсортированы сначала по расстоянию от [ 77.2, 28,6], затем по searchPriority
, а затем по dateOfGoingLive
. Чтобы ускорить эти запросы, я создал составной индекс на: isLive
, vehicleCondition
, vehicleDetails.location
(типа 2dsphere) searchPriority
и dateOfGoingLive
.
Когда я выполняю эту explain
команду:
db.vehicleinventories_latlong.find({ $query: {isLive: false, vehicleCondition: "USED", "vehicleDetails.city": {$in: ["New Delhi", "Delhi", "Gurugram"]}, "vehicleDetails.location": { $nearSphere: { $geometry: { type: "Point", coordinates: [ 77.2, 28.6 ] }, $maxDistance: 100 * 1000 } }}, $orderby: {searchPriority: -1, dateOfGoingLive: -1} }).explain()
Это просто предыдущая команда запроса с .explain()
в конце.
Это результат, который я получаю на MongoShell:
https://pastebin.com/qEvUNju0 (i have removed some parts of the output because it did not fit the 512K limit for pastebin)
Это довольно долго, и я не знаю, как интерпретировать эти результаты. Я вижу, что используется индекс, но почему я вижу так много vehicleDetails.location
массивов кортежей? В настоящее время в моей коллекции всего 360 документов, и только 15 документов удовлетворяют критериям этого запроса. Правильно ли я проиндексировал коллекцию для этого запроса?
This query will be exectued in response to a web request which will ask for «all LIVE, USED vehicles from cities: New Delhi, Delhi and Gurugram sorted first by distance from New Delhi, then by searchPriority and then by date of going live». The order in which I have listed city names inside the $in
clause in my query is relevant. The distance has to be measured from the first city inside the $in
clause. This means that the $nearsphere
clause in the query will have coordinates of the first city inside $in
array.
In the collection, vehicleDetails.location
coordinates will be the same for all vehicles belonging to the same city and the number of cities in my DB is quite low. With these details, do you think 2dsphere index is helping this query? How can I make these queries faster?
EDIT: Added output of getIndexKeys():
db.vehicleinventories_latlong.getIndexKeys()
[ { _id: 1 },
{ isLive: 1,
vehicleCondition: 1,
'vehicleDetails.location': '2dsphere' },
{ isLive: 1,
vehicleCondition: 1,
'vehicleDetails.location': '2dsphere',
searchPriority: 1 },
{ isLive: 1,
vehicleCondition: 1,
'vehicleDetails.location': '2dsphere',
searchPriority: 1,
dateOfGoingLive: 1 },
{ isLive: 1,
vehicleCondition: 1,
'vehicleDetails.city': 1,
'vehicleDetails.location': '2dsphere',
searchPriority: -1,
dateOfGoingLive: -1 } ]