Fundamentals for Python
Storage, indexing, query planning, and security primitives for spatial graphs.
Production-ready patterns for backend, data and logistics engineers building, querying, routing and scaling spatial graph networks with Python and Neo4j / GraphDB.
This site is a focused engineering reference for shipping spatial routing systems that survive real production load. It pairs Cypher with async Python drivers, spatial indexing, and topology-aware ingestion so that distance filters, KNN searches, and shortest-path queries stay sub-second as your graph scales to millions of nodes.
You'll find concrete patterns for OSM ingestion, POI enrichment, attribute synchronization, query-planner tuning, and multi-tenant spatial security, plus a dedicated track on network routing algorithms — Dijkstra, A*, contraction hierarchies, turn restrictions, and Neo4j GDS versus hand-written Cypher — each grounded in working Python and Cypher snippets. The goal is to treat spatial predicates and shortest-path search as first-class operators, not post-processing filters.
Pick a section below to dive in. Each page links to deeper subtopics, and every code block can be copied with one click.
4 top-level sections spanning 53 pages — each section opens onto subtopics and hands-on deep-dive guides.
Storage, indexing, query planning, and security primitives for spatial graphs.
Index-backed distance filters, KNN, joins, performance tuning.
Pipelines, POI enrichment, attribute sync, async batching.
Dijkstra, A*, contraction hierarchies, turn restrictions, GDS vs Cypher.
Hands-on deep dives that put the patterns to work end to end — the best place to begin if you learn by reading working Python and Cypher.
You need the set of every location a depot can reach within 10, 20, and 30 minutes of driving, drawn as nested drive-time bands. The symptom that brings people…
A radius query that works flawlessly over Europe returns an empty set the instant an operator runs it near Fiji, the Aleutians, or Kiribati — and no error is…
The symptom is a batch job that maps a few thousand pickup events to their nearest road nodes in staging in under a second, then wedges for minutes and blows…
A fleet telematics feed reports a vehicle at a point that lands in the middle of a block, tens of meters from any intersection. Snap it to the nearest node and…
Two Neo4j features answer to the name "kNN" and they are not interchangeable. gds.knn builds an approximate k-nearest-neighbor graph over node properties…
A spatial service that compiles fine under light traffic starts burning CPU on query planning the moment real request volume arrives — flame graphs point not…
A dispatch query that ran in milliseconds against a seed graph suddenly takes forty seconds in production, and the query log shows one operator responsible: a…
A variable-length MATCH over a dense road or transit network expands combinatorially, and if you compute spherical distance after the paths are materialized…
A regional .osm.pbf extract is a few gigabytes on disk and tens of gigabytes once its nodes, ways, and relations are materialized as Python objects. The naive…
A bounding-box or proximity query over millions of Location nodes suddenly costs hundreds of milliseconds, and PROFILE shows a NodeByLabelScan feeding a Filter…
Someone posts a benchmark showing GDS Dijkstra is "50× faster than Cypher," and someone else posts one showing the opposite, and both ran real code. The reason…
A router that costs every edge at free-flow speed returns a path that is optimal at 3 a.m. and wrong at 8 a.m. The symptom is an ETA that is confidently twenty…
The symptom is a route that tells a driver to make a turn a sign forbids. The root cause is structural: in a node-based road graph a junction is a single…
The query side of a contraction hierarchy is only ever as good as the shortcuts the preprocessing produced, and this is exactly where builds go wrong: contract…
When a route query needs weighted shortest paths at scale — a single source to one target, or a source to every reachable node as a cost surface — the…
A\ is only as good as its heuristic, and the most common way engineers break it is subtle: they wire the straight-line Haversine distance in metres straight…
The symptom that brings teams here is a routing graph whose pathfinding latency creeps from sub-100ms into the high hundreds the moment a live demographics…
Analysts ask the graph for "all charging stations in Bavaria" or "delivery hubs inside the Paris city limits," and the query has nothing to filter on — the POI…
A continental OpenStreetMap extract contains tens of millions of directed edges, and a single urban intersection alone can spawn dozens of relationships…
An OpenStreetMap importer that parses features faster than Neo4j can absorb them has exactly two ways to die: it exhausts the connection pool or it exhausts…
The symptom that brings teams to this page is a routing graph that slowly goes wrong while the loader reports success: traffic-speed updates land out of order…
The symptom that brings teams to this page is a routing graph that quietly diverges from its system of record: a point of interest that closed weeks ago still…
A tenant-scoped radius query that leans on a native point index seeks the bounding box first and checks tenancy last. On a shared graph that is exactly…
Cross-tenant data leakage in spatial routing graphs rarely starts with broken authentication — it starts with an unscoped index. The symptom is a logistics…
A routing engine returns a "no path found" between two streets that visibly cross on the map, or it reports a detour twice the real distance. The symptom…
Two streets that visibly meet on the map route as if they were on separate continents, because their shared corner was digitized as two vertices a millionth of…
A spatial query that returns forty rows can still read forty million. The gap between what a routing query returns and what it touches is invisible in the…
The symptom is narrow and infuriating: a proximity query that ran as a PointIndexSeekByRange in staging quietly regresses to a NodeByLabelScan in production…
Logistics routing engines and mobility analytics platforms routinely see p99 latency blow out when a spatial proximity filter sits in the same MATCH clause as…
Routing solvers collapse the moment raw OpenStreetMap data reaches production with unresolved topological fragmentation: shortest-path queries return null…
Most road-graph teams pick a spatial index once, by reflex, and pay for it later. The default reflex is Neo4j's native point index — an R-tree variant — and…
Dispatch services that answer "which depots are closest to this drop-off?" stall the moment the query touches every LogisticsHub node: with no spatial index…