PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment puis-je obtenir les k voisins les plus proches pour geodjango?

Vous pouvez utiliser un raw() requête sql pour utiliser postgis order_by opérateurs :

  1. <-> qui obtient le voisin le plus proche en utilisant les centres des boîtes englobantes pour calculer les distances inter-objets.

  2. <#> qui obtient le voisin le plus proche en utilisant les boîtes englobantes elles-mêmes pour calculer les distances inter-objets.

Dans votre cas, celui que vous voulez semble être le <-> opérateur, donc la requête brute :

knn = Person.objects.raw(
    'SELECT * FROM myapp_person 
    ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
    [location.x, location.y]
)[:k]

MODIFIER en raison de sa propre négligence : Vous pouvez omettre le [:k] pour ajouter LIMIT 1 sur la requête SQL brute. (N'utilisez pas les deux comme je l'ai fait !)

En train de répondre à votre autre question :Est-il efficace de commander par distance (table entière) dans geodjango ,une autre solution peut-être possible :

En activant l'spatial indexing et en affinant votre requête par des contraintes logiques (comme expliqué dans ma réponse de la question ci-dessus), vous pouvez obtenir un KNN assez rapide requête comme suit :

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]