🎯 ATIVIDADE 16 — CONECTANDO OS PONTOS

📖 Fundamentação Teórica

Para realizar este laboratório com sucesso, certifique-se de ter compreendido os conceitos apresentados no:
👉 CAPÍTULO 16: VIEWS, ÍNDICES E OTIMIZAÇÃO

Bem-vindo à décima sexta semana (4 aulas) do curso de Banco de Dados. Em modelos de dados relacionais clássicos, modelar redes altamente conectadas (como redes sociais com milhões de amigos, sistemas de recomendação baseados em curtidas comuns ou rotas de frete interconectadas) é um pesadelo técnico de performance, pois exige dezenas de JOINS lentos. Hoje, conheceremos o Neo4j, a ferramenta mais poderosa para bancos de dados de Grafos (Graph Database), e aprenderemos a linguagem Cypher para navegar por relações complexas instantaneamente. 🛡️🕸️


🎯 Objetivos de Aprendizagem do Laboratório

Ao final deste laboratório prático (estimativa: 4 horas presenciais / autoguiadas), você será capaz de:

  • Compreender a diferença prática entre Tabelas (SQL) e Relações de Grafos (Nós e Arestas).
  • Instalar e executar o Neo4j localmente através do Docker Desktop ou Neo4j Desktop.
  • Dominar comandos de modelagem física e busca em linguagem Cypher.
  • Criar Nós (Nodes), Propriedades (Properties) e Relacionamentos (Relationships) no Grafo.
  • Consultar rotas e encontrar o caminho mais curto usando funções de busca.

🏢 O Cenário Prático (Seu Desafio)

O departamento de roteamento de Last Mile da TecProExpress quer otimizar a distribuição de entregas no Sudeste do Brasil. Eles precisam de um mapa interativo onde:

  1. Cidades são pontos de conexão (Nós).
  2. Rodovias que conectam essas cidades são as conexões (Relacionamentos).
  3. Cada relacionamento tem uma propriedade física de Custo/Distância em quilômetros.

Seu desafio é criar essa malha viária em formato de Grafo no Neo4j e executar uma busca em Cypher para encontrar a melhor rota e calcular a distância total de transporte entre São Paulo e Belo Horizonte.


🧠 Fundamentos: A Teoria Traduzida

A Anatomia dos Grafos

Diferente de tabelas que possuem linhas de grade, os bancos de grafos utilizam a matemática de Grafos para armazenar e organizar informações:

graph LR
    SP(("Cidade: São Paulo")) -- "RODOVIA {distancia: 430}" --> RJ(("Cidade: Rio de Janeiro"))
    SP -- "RODOVIA {distancia: 580}" --> BH(("Cidade: Belo Horizonte"))
    RJ -- "RODOVIA {distancia: 440}" --> BH
    style SP fill:#bbdefb,stroke:#1e88e5
    style RJ fill:#bbdefb,stroke:#1e88e5
    style BH fill:#bbdefb,stroke:#1e88e5
  • Nó (Node): A entidade do mundo real (ex: uma Cidade, uma Pessoa ou um Pedido).
  • Relacionamento (Relationship / Edge): A conexão física direcionada entre dois nós. Possui obrigatoriamente um Tipo de Relação (ex: -[:RODOVIA]->).
  • Propriedade (Property): Pares de chave-valor salvos nos nós ou nos relacionamentos (ex: nome: "São Paulo", distancia: 430).

Linguagem Cypher (Analogia de Busca):

Cypher é uma linguagem baseada em artes ASCII desenhadas em formato de texto para facilitar o reconhecimento visual dos relacionamentos pelo programador:

  • () representa um (símbolo de círculo).
  • [] representa um Relacionamento (símbolo de caixa).
  • --> representa o direcionamento da conexão (uma seta física).

📖 Exemplo Guiado: Criando o Primeiro Grafo

1. Inicializando o Neo4j via Docker Terminal

Execute o comando abaixo no terminal do PowerShell/Bash:

docker run --name neo4j-tecpro -p 7474:7474 -p 7687:7687 -d -e NEO4J_AUTH=neo4j/senha_forte_123 neo4j

(Nota: A porta 7474 serve para o console de interface web do Neo4j, e a porta 7687 serve para tráfego binário de dados via Bolt).

2. Acessando a Interface de Consulta (Neo4j Browser)

Abra seu navegador e digite o endereço: http://localhost:7474. Faça login com o usuário neo4j e a senha definida senha_forte_123.

3. Criando as Cidades no Grafo (Comando Cypher)

// Criando três cidades no Neo4j
CREATE (sp:Cidade {nome: "São Paulo", estado: "SP"})
CREATE (rj:Cidade {nome: "Rio de Janeiro", estado: "RJ"})
CREATE (bh:Cidade {nome: "Belo Horizonte", estado: "MG"})

4. Estabelecendo Conexões (Relacionamentos)

// Buscando as cidades criadas e criando as rodovias
MATCH (sp:Cidade {nome: "São Paulo"}), (rj:Cidade {nome: "Rio de Janeiro"})
CREATE (sp)-[:RODOVIA {distancia: 430}]->(rj)

🛠️ Prática Obrigatória 1: Criando a Malha Sudeste

  1. Acesse o painel do seu Neo4j Browser.
  2. Crie as cidades de São Paulo, Rio de Janeiro e Belo Horizonte.
  3. Crie os seguintes relacionamentos de estradas no seu painel:
    • São Paulo para Rio de Janeiro com distância de 430 km.
    • Rio de Janeiro para Belo Horizonte com distância de 440 km.
    • São Paulo para Belo Horizonte com distância de 580 km (Rodovia direta Fernão Dias).
  4. Escreva a consulta em Cypher para recuperar todos os nós da sua tela.

💻 Execução de Consultas Cypher no Terminal (cypher-shell)

Para testar consultas de grafos logísticos via terminal cypher-shell:

// Buscando conexões rodoviárias a partir de São Paulo
MATCH (origem:Cidade {nome: "São Paulo"})-[r:RODOVIA]->(destino:Cidade)
RETURN origem.nome AS de, destino.nome AS para, r.distancia AS km;

🖥️ Saída Esperada no Terminal do cypher-shell:

+------------------------------------------+
| de          | para             | km      |
+------------------------------------------+
| "São Paulo" | "Rio de Janeiro" | 430     |
| "São Paulo" | "Belo Horizonte" | 580     |
+------------------------------------------+
2 rows available.
🌐 [NEO4J] Relações indexadas de ponteiro direto navegadas em 0.8ms.

🌐 Requisição cURL para Rota Mais Curta em Grafo (Swagger /docs)

curl -X POST "http://127.0.0.1:8000/api/v1/rotas/grafo" \
     -H "Content-Type: application/json" \
     -d '{
       "origem": "São Paulo",
       "destino": "Rio de Janeiro",
       "criterio": "MENOR_DISTANCIA"
     }'

🔹 Resposta JSON:

{
  "origem": "São Paulo",
  "destino": "Rio de Janeiro",
  "distancia_total_km": 430,
  "caminho_nos": ["São Paulo", "Rio de Janeiro"]
}

🛠️ Prática Obrigatória 2: Buscando Caminhos no Grafo

  1. Escreva uma consulta em Cypher que localize todas as cidades conectadas diretamente a São Paulo.
  2. Escreva uma consulta em Cypher que localize as rodovias cuja distância seja menor do que 500 km.

📤 Instruções de Entrega (Microsoft Teams)

Após validar suas consultas de Grafos no Neo4j Browser:

  1. Salve todas as queries de criação e busca Cypher em um arquivo com a extensão .cypher ou .txt (Ex: Atividade_16_SeuNome.cypher).
  2. Anexe uma captura de tela mostrando a visualização gráfica (o desenho de bolas e setas interconectadas) gerada na tela do Neo4j Browser.
  3. Envie o arquivo de texto e o print na tarefa correspondente no Teams.

💡 Checkpoint de Lógica

Importante

Índices de Relacionamentos: Em bancos SQL, buscar caminhos indiretos (ex: Amigo do Amigo do Amigo) exige processar cruzamentos de tabelas inteiras na memória temporária. No Neo4j, as relações são salvas fisicamente com ponteiros diretos de memória nos nós. Isso faz com que navegar por relações complexas demore frações de milissegundos, independente do tamanho total do banco de dados! 🧠🛡️

---

📊 Rubrica Formativa de Avaliação

Critério de Avaliação Insuficiente (0% - 40%) Regular (41% - 70%) Excelente (71% - 100%)
Modelagem em Grafo (Nós & Relacionamentos Cypher) Erros na sintaxe Cypher (`CREATE`/`MATCH`) ou sem propriedades nas arestas. Cria os nós de cidades mas sem conectar com a rodovia e distância. Malha viária em grafo impecável conectando nós de cidades através de relacionamentos orientados (`:RODOVIA`) com propriedades de distância.
Consultas de Caminhos & Desempenho (MATCH) Não consegue formular buscas `MATCH` com filtros de distância. Executa a busca mas sem filtrar o limite de 500 km. Queries Cypher avançadas retornando caminhos diretos, filtros de distância e navegabilidade por ponteiros de memória.
Entrega & Visualização Gráfica Entrega arquivo sem a sintaxe Cypher. Entrega os comandos Cypher mas sem a imagem do grafo no Neo4j Browser. Submete `.cypher`/`.txt` acompanhado de print mostrando a teia visual interconectada no Neo4j Browser.

🔥 Desafio de Fixação (Opcional)

Nível: Cientista de Dados de Redes 🏆

Pesquise sobre funções matemáticas em Cypher. Como você utilizaria o operador MATCH p = shortestPath(...) para fazer o Neo4j calcular automaticamente qual é o caminho mais curto físico entre São Paulo e Belo Horizonte na malha viária?


🔑 Gabarito de Código/Fórmulas Completo

Painel Cypher (Gabarito Oficial)

// Prática 1: Criação da Malha Viária
// Passo 1 — cria as três cidades
CREATE (sp:Cidade {nome: "São Paulo", estado: "SP"}),
       (rj:Cidade {nome: "Rio de Janeiro", estado: "RJ"}),
       (bh:Cidade {nome: "Belo Horizonte", estado: "MG"});

// Passo 2 — São Paulo -> Rio de Janeiro (statement isolado, variáveis próprias)
MATCH (a1:Cidade {nome: "São Paulo"}), (b1:Cidade {nome: "Rio de Janeiro"})
CREATE (a1)-[:RODOVIA {distancia: 430}]->(b1);

// Passo 3 — Rio de Janeiro -> Belo Horizonte (statement isolado, variáveis próprias)
MATCH (b2:Cidade {nome: "Rio de Janeiro"}), (c2:Cidade {nome: "Belo Horizonte"})
CREATE (b2)-[:RODOVIA {distancia: 440}]->(c2);

// Passo 4 — São Paulo -> Belo Horizonte (statement isolado, variáveis próprias)
MATCH (a3:Cidade {nome: "São Paulo"}), (c3:Cidade {nome: "Belo Horizonte"})
CREATE (a3)-[:RODOVIA {distancia: 580}]->(c3);
// Prática 2: Consultas
// 1. Cidades conectadas diretamente a São Paulo
MATCH (sp:Cidade {nome: "São Paulo"})-[r:RODOVIA]->(destino)
RETURN destino.nome, r.distancia;

// 2. Rodovias com distância menor que 500km
MATCH (origem)-[r:RODOVIA]->(destino)
WHERE r.distancia < 500
RETURN origem.nome, destino.nome, r.distancia;

🔍 Explicação do Gabarito:

  • MATCH: Cláusula que localiza padrões geométricos descritos em formato ASCII.
  • -[r:RODOVIA]->: Identifica e atribui a variável r ao relacionamento para podermos filtrar ou exibir as propriedades dele.
  • shortestPath: O algoritmo interno do Neo4j varre os ponteiros de memória em largura (Breadth-First Search) para achar o menor número de saltos físicos instantaneamente.