Teu progresso
0 / 83 módulos0%
Estágio 02 · 02-16
BloqueadoAlgumas queries são natural-mente caminhos em grafos: amigos de amigos, recomendação por co-purchase, fraud rings, dependências entre serviços, conhecimento corporativo, roteamento (Logística!). SQL pode resolver, JOINs recursivos, CTEs, mas vira ilegível e lento à medida que profundidade cresce.
Graph databases (Neo4j, Memgraph, ArangoDB, JanusGraph, AWS Neptune) tratam relacionamento como cidadão de primeira classe. Queries declarativas (Cypher, Gremlin, SPARQL) expressam "encontre caminho de A pra B com restrições" diretamente. Indexação de adjacency e algoritmos builtin (PageRank, betweenness, shortest path) executam em milissegundos onde SQL recursivo demora segundos.
Este módulo é graph DB por dentro: property graph model, native vs non-native graph (storage), Cypher (mais comum), traversal patterns, graph algorithms (BFS/DFS/Dijkstra/A*/PageRank/community detection), e quando NÃO usar graph DB (relacionamento simples cabe em SQL com índice; profundidade rasa não justifica nova stack).
(subject, predicate, object). Web semântica, ontologias, SPARQL. Dataset abertos (DBpedia, Wikidata).Property graph é mais conveniente pra apps; RDF brilha em integração de fontes heterogêneas e raciocínio formal.
Native graph storage (Neo4j, Memgraph): adjacency direta, pointer hopping. Traversal é cache-friendly. Non-native (graph layer sobre KV ou doc DB): traversal traduz em scans. Mais flexível em deployment, mas pode ter custo de hop.
Native shines em deep traversals (4+ hops). Non-native ok pra rasos.
Cypher (Neo4j) e openCypher (Memgraph, AWS Neptune adoption) usam ASCII art:
MATCH (u:User {id: $userId})-[:FRIEND]->(f)-[:FRIEND]->(fof)
WHERE NOT (u)-[:FRIEND]->(fof) AND u <> fof
RETURN fof.name, count(*) as common_friends
ORDER BY common_friends DESC
LIMIT 10
Sintaxe lê como o pattern: nodes em parênteses, relationships em colchetes com setas. MATCH, WHERE, RETURN, OPTIONAL MATCH, WITH (encadeia subqueries), MERGE (upsert).
Cypher suporta *N..M em relationships:
MATCH path = (a:Stop)-[:NEXT*1..5]->(b:Stop)
WHERE a.id = $start AND b.id = $end
RETURN path, length(path) ORDER BY length(path) LIMIT 1
Encontra caminhos de 1 a 5 hops. Sem profundidade, pode explodir, sempre limite.
Neo4j tem label/property index (B-Tree style) pra encontrar start nodes. Traversal subsequente é por adjacency, não índice.
Indexes textuais (full-text via Lucene), spatial (point), composite. Constraint unique disponível.
Bibliotecas de graph DBs (Neo4j GDS, Memgraph MAGE) entregam algoritmos:
Estes são algoritmos clássicos (01-05) com implementações otimizadas pra graph storage.
Regra: substantivos com identidade = nodes. Verbos/relacionamentos = edges. Properties em ambos.
Mas granularidade importa. Caso clássico: order com items.
(:Order)-[:CONTAINS]->(:Item). Se Item é compartilhado (mesmo SKU em vários orders), bom.(:Order)-[:CONTAINS {qty: 3}]->(:Product). Quantity vira property da edge, natural pra muitos:muitos com atributos.Anti-pattern: tudo node. Edges com properties são poderosos, use.
Neo4j ACID, transações multi-statement. Cluster mode usa Raft pra core (writes), read replicas. Em deploys grandes, sharding (Neo4j Fabric) divide por subdomínio mas adiciona complexidade.
Memgraph: in-memory, persistência via WAL+snapshots; transações ACID.
Regra: se você está escrevendo CTEs recursivos e queries com 4+ joins explorando relacionamentos, considere graph. Se não, fique em SQL.
Postgres com ltree (labels hierárquicas), WITH RECURSIVE (CTEs), e hand-rolled adjacency lists resolvem grafos médios. Extension Apache AGE roda Cypher sobre Postgres.
Trade-off: stack única, sem precisar de Neo4j. Mas perde algoritmos otimizados nativos.
Confusão comum. GraphQL é API query language (04-05), executada por resolvers que falam com qualquer storage (incluindo SQL). Graph DB é storage. GraphQL pode usar graph DB ou não.
Hop count é principal cost driver. Latency cresce ~ linear com profundidade (em native), exponencial com fan-out (sem filtro).
Optimization patterns:
*1..5, não *.Backups: hot backup com snapshot + replication. Neo4j Aura (managed). Sizing: dataset cabe em RAM idealmente; warm cache crítico.
Migration: import via LOAD CSV, apoc.periodic.iterate. Batch sizes 10k-50k.
Monitoring: Bolt protocol metrics, slow query log, page cache hit ratio.
ISO/IEC 39075:2024 (GQL) é primeiro standard internacional pra graph query language. Cypher é base. Adoção por Neo4j, AWS Neptune, TigerGraph. Vale acompanhar.
Graph DB perde 90% das vezes pra Postgres + JOIN. Mas em 10% dos casos (multi-hop traversal, recommendation, fraud detection com cycles, knowledge graph), Postgres com 6-level JOIN explode em latência cubica enquanto Neo4j responde em 50ms. Esta seção entrega: 5 padrões Cypher production-ready, decisão "graph vs SQL" com benchmarks reais, integração híbrida (Postgres source + Neo4j projeção), tooling 2026.
| Cenário | Por que graph vence |
|---|---|
| Multi-hop traversal (4+ hops) | SQL: N JOINs cubic; Neo4j: index-free adjacency O(N) |
| Pathfinding (shortest path, all paths) | SQL: recursive CTE complexa; Neo4j: shortestPath nativo |
| Pattern matching (subgraphs, motifs) | SQL: vira janela de UNION ALL gigante; Cypher: declarativo |
| Variable depth ("amigos de amigos com filtro") | SQL: recursive CTE com depth dinâmica = pesadelo; Cypher: *1..5 |
MATCH (me:Courier {id: $courierId})-[:WORKED_WITH*2..3]-(suggestion:Courier)
WHERE NOT (me)-[:WORKED_WITH]-(suggestion)
AND suggestion.id <> me.id
AND suggestion.active = true
WITH suggestion, count(*) AS strength
ORDER BY strength DESC
LIMIT 10
RETURN suggestion.id, suggestion.name, strength;
SQL equivalente requer 2-3 self-joins + DISTINCT + window function. Em 1M couriers com avg 50 collaborations, Postgres p99 ~3s; Neo4j ~80ms.
// Detecta ciclo de pagamentos suspeito (lojista -> courier -> lojista) em janela
MATCH (l1:Lojista)-[t1:PAID]->(c:Courier)-[t2:PAID]->(l2:Lojista)
WHERE t1.amount > 10000 AND t2.amount > 10000
AND t1.timestamp < t2.timestamp
AND duration.between(t1.timestamp, t2.timestamp).hours < 24
AND l1.id <> l2.id
RETURN l1, c, l2, t1.amount, t2.amount;
SQL: 3-way JOIN com timestamp diff + duration aggregation + nondiagonal filter. Cypher é literal o pattern. Estende fácil pra N-hop: (l1)-[*1..6]->(l_back) detecta cycles longos.
MATCH (origin:Hub {city: 'São Paulo'}), (dest:Hub {city: 'Recife'})
CALL apoc.algo.dijkstra(origin, dest, 'CONNECTS', 'distance_km')
YIELD path, weight
RETURN [n IN nodes(path) | n.city] AS route, weight AS totalKm;
APOC plugin: Dijkstra, A*, all shortest paths. 50ms em grafo de 1M nodes.
// Customers que compraram products parecidos a um specific
MATCH (target:Product {id: $productId})<-[:BOUGHT]-(buyer:Customer)-[:BOUGHT]->(rec:Product)
WHERE rec.id <> target.id
AND rec.category = target.category
AND NOT (target)<-[:SIMILAR_TO]-(rec)
WITH rec, count(DISTINCT buyer) AS coBuyers
WHERE coBuyers >= 5
RETURN rec.id, rec.name, coBuyers
ORDER BY coBuyers DESC
LIMIT 20;
MATCH (c:Customer {id: $customerId})
CALL apoc.path.subgraphAll(c, {
relationshipFilter: 'BOUGHT|RATED|REVIEWED',
maxLevel: 2
})
YIELD nodes, relationships
RETURN nodes, relationships;
Output vira input pra GNN (Graph Neural Network) ou export pra feature store.
| Approach | Bom em | Limita em |
|---|---|---|
| Neo4j / Memgraph (dedicated) | Multi-hop, complex traversal, OLTP graph | OLTP relacional misto; ops separate |
| Postgres + recursive CTE | < 4 hops, < 1M nodes | Latency cresce cubic; código complexo |
| Postgres + Apache AGE (graph extension) | Graph + relational mesma DB | Newer; performance vs Neo4j ainda atrás |
| Postgres + ltree | Hierarchies (single tree) | Não generalist graph |
Postgres (source of truth OLTP)
|
v CDC (Debezium)
Kafka
|
v Consumer
Neo4j (graph projection: subset relevante)
^
| Read-only graph queries
App
CREATE INDEX FOR (c:Customer) ON (c.id);CREATE CONSTRAINT FOR (c:Customer) REQUIRE c.id IS UNIQUE;MATCH (a), (b) sem WHERE relacionando = NxM. Sempre conecte com edge.*1.. (unbounded) explode. Sempre cap: *1..5.WHERE n.email = $x sem index = full node scan.$param) cacheiam; literal values cada vez planejam de novo.| Tool | Modelo | Forte | Custo |
|---|---|---|---|
| Neo4j 5.x | Cypher; market leader | Maturity; ecosystem; APOC plugins | Community grátis; Enterprise paga |
| Memgraph | Cypher-compatible, in-memory | 100x faster pra streaming graph | Community grátis; Enterprise paga |
| Apache AGE (Postgres extension) | OpenCypher dialect | Graph + relational mesmo DB | Free, Postgres ecosystem |
| TigerGraph | GSQL (própria); enterprise | Massive scale (10B+ edges) | Enterprise paga |
| Amazon Neptune | Cypher + Gremlin + SPARQL | AWS managed | Pay per hour |
| Dgraph | GraphQL native + DQL | API-friendly; horizontal scale | Open source + cloud |
* (unbounded) num grafo denso = query roda por horas, OOM.(a)-[:KNOWS]-(b) undirected; pode bater 2x na traversal.UNWIND + batched arrays.OPTIONAL MATCH em loop sem WITH: pode explodir cartesian.MATCH (n)-[*]->(m) sem upper bound em depth: combinatorial explosion em grafos densos, query nunca termina, lock + OOM. Sempre [*1..5] ou similar com cap explícito por workload.DETACH DELETE em produção sem WHERE específico: Neo4j/Memgraph não tem confirm interativo; MATCH (n) DETACH DELETE n dropa o grafo inteiro silent. Use transaction com LIMIT + dry-run RETURN count(*) antes; backup snapshot obrigatório.Cruza com 02-16 §2.10 (Postgres híbrido — pattern recomendado), 02-16 §2.12 (casos de uso reais), 04-13 §2.12 (CDC alimenta Neo4j projection), 04-10 §2.x (GNN consome subgraph extraction), 02-09 §2.7.1 (JSONB indexing pra grafos pequenos no Postgres).
Cypher pattern matching resolve traversal e subgrafo. Mas problemas reais — "quem é influente?", "quais clusters existem?", "qual rota alternativa?", "tem fraud ring?" — exigem algoritmos clássicos rodando em escala. SQL com recursive CTE bate na parede em ~3 hops ou ~100k nodes. Graph algorithms (Neo4j GDS, Memgraph MAGE) escalam a milhões de nodes com implementações otimizadas. Esta seção entrega: stack 2026, 6 famílias de algoritmos com Cypher production-ready, pattern Logística end-to-end, GraphRAG (LLM + graph), anti-patterns.
| Tool | Modelo | Forte | Limita |
|---|---|---|---|
| Neo4j GDS 2.10+ | 60+ algoritmos embedded em Neo4j 5.x | Maturity, named graph projections, ecossistema | Enterprise paga pra cluster mode |
| Memgraph MAGE 2024+ | Open-source GDS alternative | Performance competitiva, in-memory streaming | Ecosystem menor que Neo4j |
| Apache AGE (Postgres) | Cypher dialect + algoritmos básicos | Stack única (Postgres) | Imaturo; faltam Louvain, GDS-grade |
| NetworkX (Python) | In-memory; análise/research | Rápido pra prototipagem | < 100k nodes; não-distribuído |
| GraphFrames (Spark) | Distributed batch | Bilhões de nodes; PageRank/CC at scale | Latência de batch; não OLTP |
| TigerGraph | GSQL; massive parallel | 10B+ edges; enterprise | Custo; curva GSQL |
Default Logística: Neo4j 5.x + GDS 2.10+ (managed Aura ou self-host).
Iterativo: importância de um node = soma da importância de inbound neighbors / out-degree. Damping factor 0.85 default (random restart probability 0.15). Use cases: link analysis, identificar lojistas/couriers influentes, recommendation seeds.
// Projetar named graph (uma vez; reuse em multiple algoritmos)
CALL gds.graph.project(
'lojista-graph',
'Lojista',
{ REFERRED: { orientation: 'NATURAL' } }
);
CALL gds.pageRank.stream('lojista-graph', {
maxIterations: 20,
dampingFactor: 0.85
})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS lojista, score
ORDER BY score DESC
LIMIT 10;
Variants: Personalized PageRank (start de seed nodes específicos — ideal pra "similar a este customer"); Article Rank (variant pra grafos esparsos onde PageRank original distorce).
Use cases: customer segmentation, fraud rings (clusters densos suspeitos), social groups.
CALL gds.louvain.stream('courier-collab-graph', {
relationshipWeightProperty: 'shared_routes_count'
})
YIELD nodeId, communityId
RETURN communityId, COUNT(*) AS size, COLLECT(gds.util.asNode(nodeId).name) AS members
ORDER BY size DESC;
Pré-validate: se o grafo tem modularidade fraca (sem clusters claros), Louvain devolve lixo. Eyeball amostra antes de confiar.
Dijkstra: weighted shortest path, single source → single target. Yen's k: top-K rotas alternativas (route planning, fallback).
MATCH (start:Address {id: 'pickup-123'}), (end:Address {id: 'dropoff-456'})
CALL gds.shortestPath.yens.stream('road-network', {
sourceNode: start,
targetNode: end,
k: 3,
relationshipWeightProperty: 'distance_km'
})
YIELD path, totalCost
RETURN path, totalCost
ORDER BY totalCost
LIMIT 3;
BFS (unweighted) devolve hops, não km — só use quando distance não importa.
Closed cycles em payment/referral networks indicam kickback ou fraud rings. Algoritmo: BFS com depth limit ou graph pattern matching direto.
// 3-cycle de referrals (lojista A -> B -> C -> A)
MATCH (a:Lojista)-[:REFERRED]->(b:Lojista)-[:REFERRED]->(c:Lojista)-[:REFERRED]->(a)
WHERE a.id < b.id AND b.id < c.id // dedup permutações
RETURN a.name, b.name, c.name;
Avançado: combine com payment flow + time-window (duration.between(...).hours < 24) e amount thresholds → "money laundering" patterns. Sempre cap maxDepth; cycle detection sem limite explode combinatorialmente.
Logística: betweenness identifica couriers/hubs críticos — remoção colapsa entregas. Output alimenta capacity planning e SLA risk scoring.
// Sugerir colaborações entre couriers que cobrem áreas em comum mas nunca trabalharam juntos
MATCH (c1:Courier)-[:COMPLETED_DELIVERY]->(area:Area)<-[:COMPLETED_DELIVERY]-(c2:Courier)
WHERE c1 <> c2 AND NOT EXISTS((c1)-[:COLLABORATED_WITH]-(c2))
WITH c1, c2, COUNT(DISTINCT area) AS commonAreas
WHERE commonAreas >= 5
RETURN c1.name, c2.name, commonAreas
ORDER BY commonAreas DESC
LIMIT 20;
Sempre eval com ground-truth (held-out edges); sem isso, não há como saber se as recomendações servem.
Pattern: extrair entidades + relações do corpus → graph; em query time, extrair entidades da pergunta → traverse graph → enriquecer contexto pro LLM. Microsoft GraphRAG (open-source 2024) é referência.
Use case Logística: KB queries que precisam de relacionamentos entre entidades — "Quais couriers trabalharam em orders do tenant X com valor > $1k no último mês e tiveram complaint?". Vector search puro perde estrutura; GraphRAG traz a sub-rede relevante.
Watchout: entity disambiguation. Múltiplos "João Silva" colapsados em um node = respostas incorretas. Resolva com deterministic IDs + embedding similarity threshold.
Algoritmos pesados (PageRank full graph, Louvain) rodam em batch noturno; resultados materializados em property dos nodes (:Lojista {pagerank: 0.0042}) consumidos em hot path com index lookup.
maxDepth).Cruza com 02-16 §2.16 (Cypher patterns base), 02-09 (Postgres recursive CTE alternative), 04-10 (GraphRAG + LLM context), 04-13 (graph como data source pra ML / GNN), 04-09 (scaling pra billion-node distributed).
Mercado consolidado em poucas opções viáveis. Decisão por workload, não por hype.
Decision matrix:
| Workload | Escolha |
|---|---|
| OLTP graph (recommendations, fraud, social) | Neo4j 5 |
| Streaming + real-time analytics | Memgraph 3.x |
| "Graph features sem novo DB" (Postgres já existe) | Apache AGE |
| AWS-native managed | Neptune |
| Petabyte-scale, time dedicado | TigerGraph |
| Knowledge graph + RDF + reasoning | Neptune RDF / GraphDB / Stardog |
Publicado Abril 2024. Primeira ISO graph query language standard. Baseado em Cypher (Neo4j contribuiu material substancial). Objetivo: encerrar fragmentação SPARQL/Cypher/Gremlin/GSQL.
Adoption 2026:
Migration path Cypher → GQL é majoritariamente syntax-compat. Novas semantics relevantes: MATCH ... PATH com path mode (WALK, TRAIL, ACYCLIC, SIMPLE) explícito, evitando ambiguidade de cycle handling.
-- GQL path mode explícito
MATCH p = ANY SHORTEST (a:Courier)-[:DELIVERS*1..5]->(b:Region)
WHERE a.id = $courierId
RETURN p
Install + setup por session:
CREATE EXTENSION IF NOT EXISTS age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
SELECT create_graph('logistics');
Query (Cypher embedded em SQL):
SELECT * FROM cypher('logistics', $$
MATCH (c:Courier)-[:ASSIGNED]->(o:Order)-[:IN]->(r:Region)
WHERE r.code = 'SP-CENTRO'
RETURN c.name, count(o) AS orders
$$) AS (name agtype, orders agtype);
JOIN graph + relational (vantagem matadora vs Neo4j standalone):
SELECT g.name, o.total_brl, o.created_at
FROM cypher('logistics', $$
MATCH (c:Courier {id: 'CR-007'})-[:ASSIGNED]->(o:Order)
RETURN o.id AS order_id, c.name AS name
$$) AS g(order_id agtype, name agtype)
JOIN orders o ON o.id = (g.order_id::text)::int;
Pros: connection Postgres existing, transaction unified, ops sem novo DB. Cons: planner não otimizado pra deep traversal, graph algorithms ausentes, agtype casting verbose. Adopters reais: Bitnine (criador), uso interno em telecom + finance.
In-memory native, C++, Cypher + MAGE library (PageRank, community detection Louvain, betweenness, similarity). Streaming integration nativa: stream Kafka topic vira evento graph sem ETL.
CREATE KAFKA STREAM order_events
TOPICS 'orders.created'
TRANSFORM kafka_transform.order_to_graph
BOOTSTRAP_SERVERS 'kafka:9092';
START STREAM order_events;
Use case canônico: real-time fraud detection (sub-100ms graph query em 1B+ edges in-memory). Custo: RAM-bound. Planejar 1.5-2x dataset size em RAM (overhead de índices, snapshots, WAL). Dataset 100GB exige máquina 200GB RAM mínimo.
| Eixo | Property Graph | RDF Triple Store |
|---|---|---|
| Modelo | nodes/edges com properties | (subject, predicate, object) triples |
| Schema | flexible, label-based | ontology-driven (OWL, RDFS) |
| Query | Cypher / GQL | SPARQL |
| Sweet spot | OLTP, app data | knowledge graphs, reasoning, federation |
| Vendors 2026 | Neo4j, Memgraph, AGE | GraphDB, Stardog, Neptune RDF |
2026: GraphRAG pra LLMs adopta property graph (pragmatic) mais que RDF (semantic web ideology). Wikidata mantém RDF; Microsoft GraphRAG, Neo4j GenAI, LlamaIndex KG default em property graph.
Microsoft GraphRAG (paper arXiv 2404.16130, Abr 2024) reporta substantial improvements em comprehensiveness e diversity sobre vector RAG puro pra "global questions":
Stack típico 2026: Neo4j 5 + LangChain GraphCypherQAChain ou Neo4j GenAI integrations (vector index nativo desde 5.11, HNSW). Cross-ref: ver 04-10 (RAG patterns) e 04-13 (graph como input pra GNN).
dbms.memory.pagecache.size ≈ dataset size; heap separado pra query (Xmx 16-32GB típico).IN_MEMORY_ANALYTICAL desliga MVCC pra batch queries (5-10x faster, sem isolation).MATCH (:Label {prop: $val}). Sem index, full label scan.Não migrar preventively. Graph DB é overhead operacional real (cluster, backup, monitoring, query language nova pro time). Sequência:
Visualization stack 2026:
Multi-tenant isolation patterns em graph DB:
Neo4j single-DB multi-tenant é arriscado (cross-tenant leak via Cypher injection ou query mal escrita). Patterns 2026:
:Tenant_<id>; queries forçam MATCH (n:Tenant_acme) ...; risco de query developer esquecer label.WHERE n.tenantId = $tid em todo MATCH (analog a row-level security em SQL). Open-source: cypher-rewriter (community).// Anti-pattern: missing tenant filter (cross-tenant leak risk)
MATCH (u:User)-[:ORDERED]->(o:Order) RETURN u, o;
// Correct: tenant-scoped
MATCH (u:User {tenantId: $tid})-[:ORDERED]->(o:Order {tenantId: $tid}) RETURN u, o;
-- AGE + Postgres RLS combo
CREATE POLICY tenant_isolation ON ag_label.user
USING ((properties->>'tenantId')::uuid = current_setting('app.tenant_id')::uuid);
Real impact: SaaS B2B com graph dataset por tenant deveria escolher AGE + RLS antes de Neo4j multi-DB; ROI operacional brutal em > 100 tenants.
Rotas multi-stop com restrições (vehicle capacity, time windows): Memgraph in-memory pra pathfinding + replay de eventos via Kafka stream. Knowledge graph "couriers ↔ regions ↔ orders" em Apache AGE (mantém Postgres já existente, JOIN direto com tabela orders sem ETL). GraphRAG sobre tickets de suporte ("by similar issue") via Neo4j 5 + LangChain com vector index nativo.
02-16 §2.16 (Cypher patterns), 02-16 §2.17 (graph algorithms applied), ../02-09 (Postgres + recursive CTE alternative), ../../04-llms-ai/04-10 (GraphRAG context pra LLMs), ../../04-llms-ai/04-13 (graph como input pra GNN/streaming).
LOAD 'age' em cada session — query falha com function ag_catalog.cypher(...) does not exist. Carregar via session_preload_libraries ou no início de cada connection.MATCH sem index em property filtrada — full label scan, latência cresce linear com nodes. CREATE INDEX FOR (n:Order) ON (n.status).-[*]->) — explosão combinatória, query nunca retorna. Sempre [*1..5] ou similar.CALL { ... } subqueries, EXISTS patterns) que Memgraph/AGE não suportam. Portabilidade quebra silenciosamente.Fontes inline: ISO/IEC 39075:2024 (GQL standard, 12 Abr 2024); Microsoft GraphRAG paper (arXiv 2404.16130, Abr 2024); Neo4j docs 5.x; Apache AGE docs 1.5/1.6; Memgraph docs 3.x; openCypher spec.
Você precisa, sem consultar:
Estender a Logística com roteamento de entregas via graph DB.
(:Stop {id, address, lat, lng, type: 'pickup'|'dropoff'|'hub'}).(:Courier {id, vehicle_type, capacity_kg}).(:Order {id, weight_kg, deadline, status}).(s1)-[:ROAD {distance_km, avg_minutes, traffic_factor}]->(s2).(:Order)-[:PICKUP_AT]->(:Stop), (:Order)-[:DROPOFF_AT]->(:Stop).(:Courier)-[:CARRIES]->(:Order).POST /assign (atribui melhor courier).GET /route/:courier_id retorna sequência de stops com tempo previsto.WITH RECURSIVE. Compare latência e legibilidade. Documente em comparison.md.comparison.md mostra Postgres recursive ≥ 5x mais lento e mais verboso.WITH RECURSIVE + AGE.Threshold de Maestria
Acerte todas as 5 pra marcar o módulo como concluído. Sem pressa, sem timer. Tudo fica salvo no teu navegador.
Q1Qual cenário é o ponto mais forte para graph database dedicado em vez de Postgres + JOIN?
Q2Por que `MATCH (n)-[*]->(m)` (variable length sem cap) é um anti-pattern crítico?
Q3Qual a vantagem matadora de Apache AGE (graph extension do Postgres) sobre Neo4j standalone em SaaS multi-tenant?
Q4Em PageRank, para que serve o damping factor (~0.85)?
Q5Por que GraphRAG sem entity disambiguation produz respostas incorretas?
Destrava
02-16 é prereq dos seguintes módulos: