Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosAndroid Police: Samsung is smashing records! #shorts #tech #phones(21.09.2026 um 13:55 Uhr)
YouTube Security Videosheise & c't: Bundesnetzagentur wollte diesen Futterautomaten verbieten(21.09.2026 um 13:53 Uhr)
YouTube Security VideosNeil Patel: Your Google Traffic Isn't An Asset It's A Loan #shorts(21.09.2026 um 14:05 Uhr)
Windows Tipps & SecurityF-14 A Tomcat Top Gun endlich als Revell Klemmbausteinmodell erhältlich(21.09.2026 um 14:27 Uhr)
Sichere ProgrammierungShow the Hand-Back Sample Before Approving an Agent Score(21.09.2026 um 14:15 Uhr)
Sichere ProgrammierungHybrid retrieval in one Postgres query: RRF over tsvector + pgvector(21.09.2026 um 14:15 Uhr)
YouTube Security VideosAndroid Police: Samsung is smashing records! #shorts #tech #phones(21.09.2026 um 13:55 Uhr)
YouTube Security Videosheise & c't: Bundesnetzagentur wollte diesen Futterautomaten verbieten(21.09.2026 um 13:53 Uhr)
YouTube Security VideosNeil Patel: Your Google Traffic Isn't An Asset It's A Loan #shorts(21.09.2026 um 14:05 Uhr)
Windows Tipps & SecurityF-14 A Tomcat Top Gun endlich als Revell Klemmbausteinmodell erhältlich(21.09.2026 um 14:27 Uhr)
Sichere ProgrammierungShow the Hand-Back Sample Before Approving an Agent Score(21.09.2026 um 14:15 Uhr)
Sichere ProgrammierungHybrid retrieval in one Postgres query: RRF over tsvector + pgvector(21.09.2026 um 14:15 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Geolocalização Performática com Postgres e PostGIS: Uma abordagem prática no projeto Photofy

Desenvolvendo o Photofy aqui em Paulista, percebi que a busca tradicional por "cidade" era muito frustrante. Um fotógrafo que mora no Janga está colado em Olinda, mas se o cliente buscasse apenas por profissionais em "Recife", o sistema s…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Desenvolvendo o Photofy aqui em Paulista, percebi que a busca tradicional por "cidade" era muito frustrante. Um fotógrafo que mora no Janga está colado em Olinda, mas se o cliente buscasse apenas por profissionais em "Recife", o sistema simplesmente ignorava quem estava a poucos quarteirões de distância por causa de um limite invisível no banco de dados. Percebi que a geolocalização não é apenas um recurso estético; é o que faz o contrato ser viável ou não, reduzindo o custo de deslocamento para o fotógrafo e trazendo resultados reais para o cliente.






O Problema da Fronteira Invisível



O erro comum é achar que a geografia respeita o texto. Buscar por city: "Recife" é frágil porque o banco não sabe que Olinda é vizinha de Recife.



Minha primeira ideia foi a mais óbvia (o famoso Naive Approach): puxar todos os usuários do banco para o Node.js e rodar a fórmula de Haversine na mão. Mas logo vi o problema: se o Photofy crescer para 10 ou 20 mil fotógrafos, eu ia sobrecarregar a memória do servidor processando um array gigante a cada busca. A saída mais inteligente foi usar o PostGIS, deixando essa matemática pesada para a engine do PostgreSQL, que já é otimizada para isso.






Por que PostGIS? (Teoria Rápida)



Para o projeto funcionar, precisei decidir entre dois tipos de dados espaciais:




  • Geometry: Trata a Terra como um plano cartesiano.

  • Geography: Trata a Terra como um esferoide (curvo).



Escolhi o tipo Geography com o padrão SRID 4326 (WGS 84) — o mesmo usado pelo GPS dos smartphones. Isso me permitiu trabalhar com distâncias em metros de forma nativa.



Para a performance, implementei o índice GiST (Generalized Search Tree). Diferente do B-Tree comum, o GiST trabalha com "Bounding Boxes" (caixas delimitadoras). Na prática, o banco descarta instantaneamente áreas enormes (como ignorar todo o estado da Paraíba) antes mesmo de começar a filtrar os fotógrafos disponíveis em Pernambuco.






Mão na Massa: Configurando o Banco



Na hora de codar com NestJS e Prisma, a realidade foi um pouco mais desafiadora. Como o Prisma ainda é limitado com tipos espaciais nativos, o "pulo do gato" foi usar o tipo Unsupported no schema e editar a migration manualmente.






1. O Schema (prisma.schema)






model User {
// ... outros campos

// O tipo Unsupported força o Prisma a ignorar a validação JS
// mas cria a coluna correta no banco
location Unsupported("geography(Point, 4326)")?

// Índice GiST é OBRIGATÓRIO para performance
@@index([location], name: "location_idx", type: Gist)
}









2. A Migration SQL



O Prisma gera o arquivo SQL, mas precisei adicionar manualmente o comando para habilitar a extensão no topo:




-- Habilitar a extensão ANTES de criar a tabela
CREATE EXTENSION IF NOT EXISTS postgis;

-- Alterar a tabela (gerado pelo Prisma)
ALTER TABLE "users" ADD COLUMN "location" geography(Point, 4326);









Integrando ao Backend (NestJS)



Com o banco pronto, conectei o backend via Raw Queries ($queryRaw) para garantir que o índice GiST fosse realmente utilizado. Para converter endereço em coordenada (Geocoding), usei a API do Nominatim.






1. O Serviço de Geocoding (Simplificado)






// backend/src/utils/geocoding.service.ts
async getCoordinates(address: string) {
const params = new URLSearchParams({ q: address, format: 'json', limit: '1' });

// O header User-Agent é obrigatório para a API do Nominatim
const response = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, {
headers: { 'User-Agent': 'Photofy-Project' },
});

const data = await response.json();
return data[0] ? { lat: parseFloat(data[0].lat), lng: parseFloat(data[0].lon) } : null;
}









2. A Busca Espacial (O Pulo do Gato)



Aqui usamos o Raw Query para acessar as funções ST_DWithin (filtro de raio usando índice) e ST_Distance (calculo exato de metros).




// backend/src/users/users.service.ts

// Interface essencial para o TypeScript entender o retorno do banco
interface UserWithDistance {
id: string;
distance: number;
}

async findNearbyPhotographers(lat: number, lng: number, radiusKm: number) {
// ST_SetSRID cria um ponto GPS válido (WGS 84)
const result = await this.prisma.$queryRaw<UserWithDistance[]>`
SELECT
id, name,
ST_Distance(
location,
ST_SetSRID(ST_MakePoint(
${lng}, ${lat}), 4326)::geography
) as distance
FROM users
WHERE
ST_DWithin(
location,
ST_SetSRID(ST_MakePoint(
${lng}, ${lat}), 4326)::geography,
${radiusKm * 1000}
)
ORDER BY distance ASC
`
;

return result;
}









Conclusão: O Banco não é apenas um Depósito de Dados



Essa jornada no Photofy me tirou da zona de conforto do "Code First" e me fez entender que o banco de dados não é apenas um depósito de dados, mas uma engine de computação poderosa.



Delegar a lógica espacial para o PostGIS limpou meu código e protegeu o Event Loop do Node.js. Hoje, o sistema está pronto para escalar para milhares de usuários com custo computacional $O(\log N)$, conectando pessoas em Paulista, Olinda e Recife com base na distância real e não em simples comparações de texto.






Referências



NESTJS. Documentation: A progressive Node.js framework. 2024. Disponível em: https://docs.nestjs.com/. Acesso em: 11 fev. 2026.



OPENSTREETMAP FOUNDATION. Nominatim API v4.3.2 Documentation. 2023. Disponível em: https://nominatim.org/release-docs/latest/api/Overview/. Acesso em: 11 fev. 2026.



POSTGIS PROJECT. PostGIS 3.4.0 Manual. 2023. Disponível em: https://postgis.net/docs/manual-3.4/. Acesso em: 11 fev. 2026.



POSTGRESQL GLOBAL DEVELOPMENT GROUP. PostgreSQL 16.0 Documentation. 2023. Disponível em: https://www.postgresql.org/docs/16/index.html. Acesso em: 11 fev. 2026.



PRISMA DATA, INC. Prisma Documentation: Working with MongoDB, PostgreSQL, and more. 2024. Disponível em: https://www.prisma.io/docs. Acesso em: 11 fev. 2026.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Geolocalização Performática com Postgres e PostGIS: Uma abordagem prática no projeto Photofy

Thematisch verwandte Begriffe: Geolocalização, Performática, Postgres, PostGIS · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94142 | A security vulnerability has been detected in BioStar Temperature Monito…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick