Neo4j to FalkorDB Migration
Migrating graph database contents from Neo4j to FalkorDB is straightforward using standard Cypher queries to extract data, transform labels and properties as needed, and load CSV files into FalkorDB. This process migrates nodes, edges, constraints, and indexes.
Overview
The migration process consists of the following steps:
- Set up Neo4j and prepare your data
- Review and configure mapping settings
- Extract data from Neo4j to CSV files
- Load CSV data into FalkorDB
- Validate the migrated data
Prerequisites
- Neo4j instance (local or remote)
- FalkorDB instance (local, Docker, or Cloud)
- Python 3.6+
- Migration tools from the Neo4j-to-FalkorDB repository
Step 1: Setting Up Neo4j
Follow the Neo4j documentation to set up a locally run Neo4j database.
For testing purposes, you can load the Movies sample dataset by following the :guide movies command in the Neo4j browser. More details are available in the Neo4j Getting Started guide.
Step 2: Reviewing and Updating Mapping Configuration
The configuration file migrate_config.json allows you to modify how labels and properties are represented in FalkorDB.
Generating a Configuration Template
To extract the ontology from your Neo4j database and generate a template config file:
python3 neo4j_to_csv_extractor.py --password <your-neo4j-password> --generate-template <your-template>.json --analyze-only
Extractor Usage
python3 neo4j_to_csv_extractor.py [-h] [--uri URI] [--username USERNAME] --password PASSWORD
[--database DATABASE] [--batch-size BATCH_SIZE]
[--nodes-only] [--edges-only] [--indexes-only]
[--config CONFIG] [--generate-template GENERATE_TEMPLATE]
[--analyze-only] [--tenant-mode {label,property}]
[--tenant-filter TENANT_FILTER]
Options:
--uri URI: Neo4j URI (default: bolt://localhost:7687)--username USERNAME: Neo4j username (default: neo4j)--password PASSWORD: Neo4j password (required)--database DATABASE: Neo4j database name--batch-size BATCH_SIZE: Batch size for extraction--nodes-only: Extract only nodes--edges-only: Extract only relationships--indexes-only: Extract only indexes and constraints--config CONFIG: Path to migration configuration JSON file--generate-template GENERATE_TEMPLATE: Generate template migration config file--analyze-only: Only analyze topology, do not extract data--tenant-mode {label,property}: Enable multi-tenant mode - “label” (filter by node label) or “property” (filter by property value)--tenant-filter TENANT_FILTER: The label name or property name to use for tenant segregation (required with –tenant-mode)
Example Output
When analyzing a database, you’ll see output similar to:
Connecting to Neo4j at bolt://localhost:7687 with username 'neo4j'...
✅ Loaded configuration from migrate_config.json
✅ Successfully connected to Neo4j!
🔍 Analyzing Neo4j database topology...
Found 2 node labels: ['Movie', 'Person']
Found 6 relationship types: ['ACTED_IN', 'DIRECTED', 'PRODUCED', 'WROTE', 'FOLLOWS', 'REVIEWED']
📊 Analyzing node properties...
Analyzing Movie properties...
Found 3 properties: ['released', 'tagline', 'title']
Analyzing Person properties...
Found 2 properties: ['born', 'name']
🔗 Analyzing relationship properties...
Analyzing ACTED_IN properties...
Found 1 properties: ['roles']
...
📈 Gathering database statistics...
Movie: 38 nodes
Person: 133 nodes
ACTED_IN: 172 relationships
...
Step 3: Extracting Data from Neo4j
To extract data from Neo4j and generate CSV files:
python3 neo4j_to_csv_extractor.py --password <your-neo4j-password> --config migrate_config.json
The script will:
- Read data from Neo4j
- Create CSV files in the
csv_outputsubfolder - Generate headers and content based on the configuration
- Create both nodes and edges CSV files
- Export indexes and constraints
- Generate FalkorDB load scripts
Multi-Tenant Data Extraction
If your Neo4j database contains multi-tenant data, you can extract each tenant’s data into separate subdirectories:
Using property-based tenant segregation:
python3 neo4j_to_csv_extractor.py --password <your-neo4j-password> \
--tenant-mode property --tenant-filter tenantId
This will:
- Discover all distinct values of the
tenantIdproperty - Create a subdirectory for each tenant (e.g.,
csv_output/tenant_cloudserve/,csv_output/tenant_learnhub/,csv_output/tenant_shopfast/) - Export each tenant’s nodes and relationships to their respective subdirectories
- Automatically omit the
tenantIdproperty from CSV exports (since it’s encoded in the folder name)
Using label-based tenant segregation:
python3 neo4j_to_csv_extractor.py --password <your-neo4j-password> \
--tenant-mode label --tenant-filter TenantLabel
This filters nodes that have the specified label, allowing you to extract data for tenants organized by labels.
Output Files
The extraction creates the following files in the csv_output directory:
nodes_<label>.csv: One file per node labeledges_<type>.csv: One file per relationship typeindexes.csv: Database indexesconstraints.csv: Database constraintsload_to_falkordb.cypher: FalkorDB load scriptcreate_indexes_falkordb.cypher: Index creation script
Step 4: Loading CSV Data into FalkorDB
Setting Up FalkorDB
Set up FalkorDB on your local machine following the Getting Started guide.
You can use either:
- The full deployment with browser (port 3000)
- The server-only option (port 6379)
Loading Data
Load the CSV data into FalkorDB using the Python loader:
python3 falkordb_csv_loader.py MOVIES --port 6379 --stats
Options:
graph_name: Target graph name in FalkorDB (required). When using--multi-graphmode, this serves as the prefix for tenant-specific graphs--host HOST: FalkorDB host (default: localhost)--port PORT: FalkorDB port (default: 6379)--username USERNAME: FalkorDB username (optional)--password PASSWORD: FalkorDB password (optional)--batch-size BATCH_SIZE: Batch size for loading (default: 5000)--stats: Show graph statistics after loading--csv-dir CSV_DIR: Directory containing CSV files (default: csv_output)--merge-mode: Use MERGE instead of CREATE for upsert behavior--multi-graph: Enable multi-graph mode - load each tenant_* subfolder into a separate graph
Multi-Tenant Data Loading
If you extracted multi-tenant data using the --tenant-mode option, you can load each tenant into a separate FalkorDB graph:
python3 falkordb_csv_loader.py MYAPP --multi-graph --port 6379
This will:
- Scan for
tenant_*subdirectories incsv_output/ - Create a separate graph for each tenant (e.g.,
MYAPP_shopfast,MYAPP_cloudserve,MYAPP_learnhub) - Load each tenant’s data into its own isolated graph
- Provide detailed progress reporting per tenant
Example output:
🗂️ Found 3 tenant directories: ['tenant_cloudserve', 'tenant_learnhub', 'tenant_shopfast']
Each will be loaded into a separate graph
================================================================================
📊 Processing tenant: cloudserve
Target graph: MYAPP_cloudserve
Source directory: csv_output/tenant_cloudserve
================================================================================
...
✅ Completed loading tenant 'cloudserve' in 0:00:02.345
================================================================================
✅ Multi-graph loading complete!
Loaded 3 tenants into separate graphs
Total time: 0:00:07.891
================================================================================
Using FalkorDB-Loader-RS (Recommended for Large Datasets)
For significantly improved loading speed and performance, especially with large datasets, we recommend using the Rust-based FalkorDB CSV Loader.
Features
- High Performance: Built with Rust and async/await for optimal speed
- Batch Processing: Configurable batch sizes (default: 5000 records)
- Memory Efficient: Streams data without loading everything into memory
- Automatic Schema Management: Creates indexes and constraints automatically
- Merge Mode: Support for upsert operations using MERGE instead of CREATE
- Progress Reporting: Real-time progress tracking during loading
Installation
git clone https://github.com/FalkorDB/FalkorDB-Loader-RS
cd FalkorDB-Loader-RS
cargo build --release
The binary will be available at target/release/falkordb-loader.
Basic Usage
./target/release/falkordb-loader MOVIES
Advanced Usage
./target/release/falkordb-loader MOVIES \
--host localhost \
--port 6379 \
--username myuser \
--password mypass \
--csv-dir ./csv_output \
--batch-size 1000 \
--merge-mode \
--stats \
--progress-interval 500
Command-Line Options
| Option | Description | Default |
|---|---|---|
graph_name | Target graph name in FalkorDB (required) | - |
--host | FalkorDB host | localhost |
--port | FalkorDB port | 6379 |
--username | FalkorDB username (optional) | - |
--password | FalkorDB password (optional) | - |
--csv-dir | Directory containing CSV files | csv_output |
--batch-size | Batch size for loading | 5000 |
--merge-mode | Use MERGE instead of CREATE for upsert | false |
--stats | Show graph statistics after loading | false |
--progress-interval | Report progress every N records (0 to disable) | 1000 |
Performance Tips
- Adjust batch size based on your data and available memory
- Enable progress reporting for long-running imports:
--progress-interval 1000 - Use merge mode if you need to update existing data:
--merge-mode - Set log level for debugging:
RUST_LOG=info ./target/release/falkordb-loader MOVIES
For more details, see the FalkorDB-Loader-RS repository.
Example Output
Connecting to FalkorDB at localhost:6379...
✅ Connected to FalkorDB graph 'MOVIES'
Found 2 node files and 6 edge files
🗼️ Setting up database schema...
🔧 Creating ID indexes for all node labels...
Creating ID index: CREATE INDEX ON :Movie(id)
Creating ID index: CREATE INDEX ON :Person(id)
✅ Created 2 ID indexes
🔧 Creating indexes from CSV...
...
✅ Created 2 indexes from CSV
🔒 Creating constraints...
...
✅ Created 2 constraints
📥 Loading nodes...
Loading nodes from csv_output/nodes_movie.csv...
✅ Loaded 38 Movie nodes
🔗 Loading edges...
Loading edges from csv_output/edges_acted_in.csv...
✅ Loaded 172 ACTED_IN relationships
✅ Successfully loaded data into graph 'MOVIES'
📊 Graph Statistics:
Nodes:
['Movie']: 38
['Person']: 133
Relationships:
ACTED_IN: 172
DIRECTED: 44
...
Step 5: Validating Content
Validate that your data has been successfully migrated by running queries in both Neo4j and FalkorDB. Compare the results to ensure data integrity.
Example query:
MATCH p=()-[:REVIEWED]->() RETURN p LIMIT 25;
You can visualize and compare the results in both the Neo4j Browser and FalkorDB Browser to ensure the migration was successful.
Additional Resources
Next Steps
- Explore FalkorDB Cypher Language for querying your graph
- Learn about FalkorDB Operations for production deployments
- Check out FalkorDB Integration options