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â¦