Можете да използвате raw()
sql заявка за използване на postgis order_by
оператори:
-
<->
който получава най-близкия съсед, използвайки центровете на ограничителните кутии, за да изчисли разстоянията между обектите. -
<#>
който получава най-близкия съсед, използвайки самите ограничаващи полета, за да изчисли разстоянията между обектите.
Във вашия случай този, който искате, изглежда е <->
оператор, следователно необработената заявка:
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
РЕДАКТИРАНЕ поради собствена derpiness: Можете да пропуснете [:k]
за да добавите LIMIT 1
на необработената SQL заявка. (Не използвайте и двете, както направих аз!)
В процеса на отговор на другия ви въпрос:Колко ефективно е да се подрежда по разстояние (цялата таблица) в geodjango , възможно е друго решение:
Чрез активиране на spatial indexing
и стесняване на вашата заявка чрез логически ограничения (както е обяснено в моя отговор
на въпроса, свързан по-горе) можете да постигнете доста бърз KNN заявка, както следва:
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]