Możesz użyć raw()
Zapytanie sql do wykorzystania postgis order_by
operatorzy:
-
<->
który pobiera najbliższego sąsiada za pomocą środków obwiedni do obliczenia odległości między obiektami. -
<#>
który pobiera najbliższego sąsiada używając samych ramek ograniczających do obliczenia odległości między obiektami.
W twoim przypadku ten, który chcesz, wydaje się być <->
operator, czyli surowe zapytanie:
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
EDYTUJ z powodu własnej głupoty: Możesz pominąć [:k]
aby dodać LIMIT 1
w nieprzetworzonym zapytaniu SQL. (Nie używaj obu tak jak ja!)
W trakcie odpowiadania na Twoje inne pytanie:Jak efektywne jest zamawianie według odległości (cała tabela) w geodjango , możliwe jest inne rozwiązanie:
Włączając spatial indexing
i zawężenie zapytania poprzez ograniczenia logiczne (jak wyjaśniono w mojej odpowiedzi
powyższego pytania) możesz osiągnąć dość szybko KNN zapytanie w następujący sposób:
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]