You can use a raw()
sql query to utilize postgis order_by
operators:
<->
which gets the nearest neighbor using the centers of the bounding boxes to calculate the inter-object distances.
<#>
which gets the nearest neighbor using the bounding boxes themselves to calculate the inter-object distances.
In your case the one you want seems to be the <->
operator, thus the raw query:
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
EDIT due to own derpiness: You can omit the [:k]
to add LIMIT 1
on the raw SQL query. (Don't use both as I did!)
In the process of answering your other question: How efficient is it to order by distance (entire table) in geodjango ,another solution maybe possible:
By enabling spatial indexing
and narrowing down your query through logical constrains (as explained in my answer of the above -linked question) you can achieve a pretty fast KNN query as follows:
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]