sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo obtengo los k vecinos más cercanos para geodjango?

Puede usar un raw() consulta sql para utilizar postgis order_by operadores:

  1. <-> que obtiene el vecino más cercano usando los centros de los cuadros delimitadores para calcular las distancias entre objetos.

  2. <#> que obtiene al vecino más cercano utilizando los cuadros delimitadores para calcular las distancias entre objetos.

En tu caso el que quieres parece ser el <-> operador, por lo tanto, la consulta sin formato:

knn = Person.objects.raw(
    'SELECT * FROM myapp_person 
    ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
    [location.x, location.y]
)[:k]

EDITAR debido a su propia torpeza: Puede omitir el [:k] para agregar LIMIT 1 en la consulta SQL sin procesar. (¡No uses ambos como lo hice yo!)

En el proceso de responder a su otra pregunta:¿Qué tan eficiente es ordenar por distancia (toda la tabla) en geodjango ,otra solución tal vez sea posible:

Al habilitar la spatial indexing y restringir su consulta a través de restricciones lógicas (como se explica en mi respuesta de la pregunta vinculada anteriormente) puede lograr un KNN bastante rápido consulta de la siguiente manera:

current_location = me.location
people = People.objects.filter(
    location__dwithin=(current_location, D(km=50))
).annotate(
    distance=Distance('location', current_location)
).order_by('distance')[:k]