У меня есть несколько полигонов, хранящихся в GeoJSON в моем mongoDB.Оптимизация запросов GeoJSON MongoDB
Клиент отправляет список загружаемых ящиков (ящики являются ячейками регулярной сетки).
Обычный способ получить их - это сделать запрос GeoJSON с каждым полем, но он медленный, когда у меня много ящиков.
Я не хочу получать дубликаты (многоугольники, которые лежат на двух ячейках, возвращаются дважды), поэтому я делаю список извлеченных полигонов pks, чтобы игнорировать их в следующих запросах.
Дано:
box = [ [ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 0, 1 ], [ 0, 0 ] ] ] // the box to load
pks = [ ObjectId("54cf535cfe022e01ab4932f5"), ObjectId("54cf535cfe022e01ab4932f6") ] // the list of polygons already retrieved
С MongoDB, я бы что-то вроде этого:
for box in boxes:
db.places.find({ points:
{ $geoIntersects: { $geometry: { type: "Polygon" , coordinates: box } } },
{ _id: { $nin: pks } }
})
Я использую MongoEngine, поэтому у меня есть следующие:
pks = []
for box in boxes:
p = Polygon.objects(points__geo_intersects=box, pk__nin=pks)
if len(p)>0:
pks += p.scalar("id")
У меня есть три вопроса :
1. Есть ли более эффективный способ запроса полигонов с помощью этого метода?
2. Было бы быстрее использовать объект Cell, содержащий список ссылок полигонов, которые лежат на ячейке?
В MongoEngine я бы следующую модель:
class Cell(Document):
x = DecimalField()
y = DecimalField()
polygons = ListField(ReferenceField('Polygon'))
meta = {
'indexes': [[ ("x", 1), ("y", 1) ]]
}
Список коробки для загрузки бы координаты, соответствующие ячейки для загрузки.
Это дало бы с MongoEngine:
polygons = {}
for b in boxes:
cell = Cell.objects.get(x=b['x'], y=b['y'])
for polygon in cell.polygons:
if not polygons.has_key(polygon.pk):
polygons[polygon.pk] = polygon.to_json()
3. Есть ли более эффективный способ для запроса многоугольников с этим методом? (я думаю, что я должен использовать select_related(), и, возможно, можно отфильтровать многоугольники непосредственно в запросе MongoDB, чтобы избежать извлечения дубликатов)
Я только что сделал Тест: потребовалось 2,03 секунды для извлечения моих полигонов с помощью первого метода и 0,65 секунды со вторым методом. –
Hum ... На самом деле я только выяснил, что разница, вероятно, происходит от 'pk__nin = pks', которая занимает больше времени. Теперь у меня есть более быстрые результаты с первым методом ... Я продолжу расследование этого после обеда ... –