Sie können einen raw()
sql-Abfrage, um postgis order_by
zu verwenden Operatoren:
-
<->
wodurch der nächste Nachbar anhand der Mitten der Begrenzungsrahmen ermittelt wird, um die Abstände zwischen den Objekten zu berechnen. -
<#>
wodurch der nächste Nachbar mithilfe der Begrenzungsrahmen selbst ermittelt wird, um die Abstände zwischen den Objekten zu berechnen.
In Ihrem Fall scheint der gewünschte <->
zu sein Operator, also die Rohabfrage:
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
BEARBEITEN wegen eigener Schwäche: Sie können den [:k]
weglassen um LIMIT 1
hinzuzufügen auf die rohe SQL-Abfrage. (Verwenden Sie nicht beide wie ich!)
Bei der Beantwortung Ihrer anderen Frage:Wie effizient ist es, in Geodjango nach Entfernung (gesamte Tabelle) zu bestellen ,eine andere Lösung ist vielleicht möglich:
Durch Aktivieren der spatial indexing
und Eingrenzen Ihrer Abfrage durch logische Einschränkungen (wie erklärt in meiner Antwort
der oben verlinkten Frage) können Sie ein ziemlich schnelles KNN erreichen wie folgt abfragen:
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]