Puede usar un raw()
consulta sql para utilizar postgis order_by
operadores:
-
<->
que obtiene el vecino más cercano usando los centros de los cuadros delimitadores para calcular las distancias entre objetos. -
<#>
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]