您可以使用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]
EDIT由于自己derpiness:可以省略[:k]
添加LIMIT 1
上原始的SQL查询。 (像我一样,不要同时使用!)
在回答您的其他问题的过程:How efficient is it to order by distance (entire table) in geodjango,另一种解决方案也许可能:
通过启用spatial indexing
并通过逻辑约束缩小查询(为解释上述问题 - 连接的in my answer),可以实现非常快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]
对于这种情况(获得KNN),我会对使用地理栏目还是有帮助的?或者它会毫无意义 - 因为我假设涉及'<->'的计算会有所不同 – AlanSTACK
您可以使用地理列或几何图形。加快查询速度的关键是使用'spatial_idex'。 关于这个问题的进一步阅读,看看这里:https://boundlessgeo.com/2011/09/indexed-nearest-neighbour-search-in-postgis/ 祝你好运@阿兰:) –
你好,回头看看你的回答,我对'knn = Person.objects.raw('SELECT * FROM myapp_person ...')中'LIMIT 1'的目的感到困惑,我们为什么需要这个? – AlanSTACK