Anda dapat menggunakan raw()
sql query untuk menggunakan postgis order_by
operator:
-
<->
yang mendapatkan tetangga terdekat menggunakan pusat kotak pembatas untuk menghitung jarak antar objek. -
<#>
yang mendapatkan tetangga terdekat menggunakan kotak pembatas sendiri untuk menghitung jarak antar objek.
Dalam kasus Anda, yang Anda inginkan tampaknya adalah <->
operator, jadi kueri mentahnya:
knn = Person.objects.raw(
'SELECT * FROM myapp_person
ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
[location.x, location.y]
)[:k]
EDIT karena derpiness sendiri: Anda dapat menghilangkan [:k]
untuk menambahkan LIMIT 1
pada kueri SQL mentah. (Jangan gunakan keduanya seperti yang saya lakukan!)
Dalam proses menjawab pertanyaan Anda yang lain:Seberapa efisien untuk memesan berdasarkan jarak (seluruh tabel) di geodjango , solusi lain mungkin memungkinkan:
Dengan mengaktifkan spatial indexing
dan mempersempit kueri Anda melalui batasan logis (seperti yang dijelaskan dalam jawaban saya
dari pertanyaan yang ditautkan di atas) Anda dapat mencapai KNN . yang cukup cepat pertanyaan sebagai berikut:
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]