função de chamada no construtor de consultas

8

Eu tenho uma entidade de localização segurando coordenadas. Com base em um raio, quero obter todos os locais dentro do alcance.

Criei uma função (código de back-end / lógica Nestjs, não banco de dados) calculando a distância entre dois locais. Se a distância calculada for menor ou igual ao raio, desejo selecionar este local.

Minha implementação atual do repositório usando esta função de cálculo de distância:

// ...
import { distanceFromCoordinatesInKilometers } from '../shared/calculations/distanceFromCoordinatesInKilometers';

@EntityRepository(Location)
export class LocationsRepository extends Repository<Location> {
    public getLocations({ /* ... */ latitude, longitude, radiusInKilometers }: GetLocationsDTO): Promise<Location[]> {
        const query: SelectQueryBuilder<Location> = this.createQueryBuilder('location');

        // ....

        if(latitude && longitude && radiusInKilometers) {
             query.andWhere("distanceFromCoordinatesInKilometers(location.latitude, location.longitude, :latitude, :longitude) <= :radiusInKilometers", { 
                 latitude,
                 longitude,
                 radiusInKilometers, 
            });
        }

        return query.getMany();
    }
}

O exemplo mostrado acima não funciona. Eu recebo este erro

QueryFailedError: a função distanceFromCoordinatesInKilometros (precisão dupla, precisão dupla, desconhecida, desconhecida) não existe

Ao adicionar um :à função, recebo este erro

O parâmetro de função não é suportado nos parâmetros. Por favor, verifique o parâmetro "distance".

Como eu chamaria minha função de código de back-end distanceFromCoordinatesInKilometersnessa consulta? Eu posso passar variáveis ​​mas não funções?

Atualmente estou usando um banco de dados Postgres, mas seria incrível se houver uma solução independente.

Question3r
fonte
2
basicamente, você está tentando chamar uma função do seu node.jsaplicativo a partir do banco de dados, isso nunca vai funcionar, uma solução universal seria: implementar essa função no banco de dados (por exemplo, por migrações) ou mais soluções independentes de driver: implementar essa função na sua consulta
Roomy
obrigado, mas como eu implementaria essa função na minha consulta? O cálculo em si é grande (30 linhas de código)
Question3r
1
Sua pergunta está mais relacionada ao SQL que o TypeORM, mas supondo que você esteja usando um cálculo básico de círculo grande, dê uma olhada na lista principal gist.github.com/rugbyprof/…
Roomy
obrigado por esse link. Tentei traduzi-lo aqui pastebin.com/AS7y7efr e não obtive nenhum erro. Mas eu tenho que verificar se esse cálculo está correto ...
Question3r
1
Você já viu a extensão PostGIS do PostgreSQL? Ele contém funcionalidade para determinar distâncias entre coordenadas (pontos). Consulte gis.stackexchange.com/questions/77072/… para obter alguns exemplos de como obter uma consulta filtrando linhas a uma distância especificada de uma coordenada fornecida.
Timshel 30/04

Respostas:

0

OK Se você implementou o seguinte em seu código, é necessário avaliar a função antes de passá-la para a string SQL. Então simplesmente:

if(latitude && longitude && radiusInKilometers) {
             query.andWhere(`${distanceFromCoordinatesInKilometers(location.latitude, location.longitude, :latitude, :longitude)} <= :radiusInKilometers`, { 
                 latitude,
                 longitude,
                 radiusInKilometers, 
            });
        }
bluejayke
fonte
desculpe, não entendi sua resposta. Este é um projeto NestJs (Nó com TS) usando TypeORM. O que devo fazer no meu código?
Question3r
@ Question3r C edit
bluejayke
desculpe, mas isso não vai funcionar porque a função não sabe sobre os valores atuais de latlong provenientes da tabela do banco de dados aquilocation.latitude, location.longitude
Question3r