PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como faço para obter os k vizinhos mais próximos para geodjango?


Você pode usar um raw() consulta sql para utilizar postgis order_by operadores:

  1. <-> que obtém o vizinho mais próximo usando os centros das caixas delimitadoras para calcular as distâncias entre objetos.

  2. <#> que obtém o vizinho mais próximo usando as próprias caixas delimitadoras para calcular as distâncias entre objetos.

No seu caso, o que você quer parece ser o <-> operador, portanto, a consulta bruta:
knn = Person.objects.raw(
    'SELECT * FROM myapp_person 
    ORDER BY location <-> ST_SetSRID(ST_MakePoint(%s, %s),4326)',
    [location.x, location.y]
)[:k]

EDITAR devido à própria derpidez: Você pode omitir o [:k] para adicionar LIMIT 1 na consulta SQL bruta. (Não use os dois como eu fiz!)

No processo de responder sua outra pergunta:Quão eficiente é ordenar por distância (tabela inteira) no geodjango , outra solução talvez seja possível:

Habilitando a spatial indexing e restringir sua consulta por meio de restrições lógicas (conforme explicado na ​​minha resposta da pergunta vinculada acima), você pode obter um KNN bem rápido consulta da seguinte forma:
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]