neo4j-php / neo4j-laravel
A Laravel package for Neo4j integration
Requires
- php: ^8.2
- illuminate/support: ^11.0 || ^12.0 || ^13.0
- laudis/neo4j-php-client: ^3.2
Requires (Dev)
- barryvdh/laravel-debugbar: ^3.15
- friendsofphp/php-cs-fixer: ^3.69
- orchestra/testbench: ^9.0 || ^10.0
- phpunit/phpunit: ^10.5
- psalm/plugin-laravel: ^2.12
- vimeo/psalm: ^5.0
This package is not auto-updated.
Last update: 2026-07-21 03:26:16 UTC
README
A Laravel package that provides integration with Neo4j graph database.
Warning
Database Configuration Recommendations:
Laravel uses the default database connection for authentication, sessions, and other core features. While you can use Neo4j as your default database, we recommend:
- Use a traditional database (SQLite, MySQL, PostgreSQL, etc.) as your default database connection
- Use Neo4j as a secondary connection for your graph data
If you choose to use Neo4j as your default database:
- Set
SESSION_DRIVER=filein your .env file - Laravel Authentication will not work as it relies on Eloquent ORM
- Other features that depend on the default database connection may be affected
These limitations will be addressed in future releases.
Installation
composer require neo4j-php/neo4j-laravel
Configuration
Environment Variables
Add the following to your .env file:
DB_CONNECTION=neo4j NEO4J_URL=bolt://localhost:7687 NEO4J_USERNAME=neo4j NEO4J_PASSWORD=your_password NEO4J_DATABASE=neo4j
Query log flushing (NEO4J_QUERY_CHANNEL)
Each Neo4j connection keeps an in-memory query log (the same entries getQueryLog() returns; queries are still recorded by the existing logQuery() path with timing—nothing is double-logged at execution time). After each HTTP request finishes (or when a console command ends), that buffer is flushed once to Laravel’s logger as debug lines, then cleared.
| Variable | Behavior |
|---|---|
NEO4J_QUERY_CHANNEL unset or empty |
Each log line is written with Log::debug(...) (no ::channel()), so messages use your app’s default log stack from config('logging.default') (usually stack → single / laravel.log). |
NEO4J_QUERY_CHANNEL=neo4j_queries (non-empty) |
If config('logging.channels.neo4j_queries') exists, lines are written with Log::channel('neo4j_queries')->debug(...). Define that channel in config/logging.php (e.g. a daily file dedicated to Neo4j). If the name is set but not defined under logging.channels, the package falls back to the same behavior as an empty value (default logger). |
To tune or disable logging per environment, configure the channel itself in config/logging.php (e.g. level, a null driver, or omitting the channel from your production LOG_STACK).
Example: dedicated daily channel in config/logging.php:
'neo4j_queries' => [ 'driver' => 'daily', 'path' => storage_path('logs/neo4j-queries.log'), 'level' => env('LOG_LEVEL', 'debug'), 'days' => 14, ],
Then in .env:
NEO4J_QUERY_CHANNEL=neo4j_queries
Database Configuration
Add the Neo4j connection configuration to your config/database.php:
'neo4j' => [ 'driver' => 'neo4j', 'url' => env('NEO4J_URL', 'bolt://localhost:7687'), 'username' => env('NEO4J_USERNAME', 'neo4j'), 'password' => env('NEO4J_PASSWORD', ''), 'database' => env('NEO4J_DATABASE', 'neo4j'), 'auth_scheme' => env('NEO4J_AUTH_SCHEME', 'basic'), 'ssl' => [ 'mode' => env('NEO4J_SSL_MODE', 'from_url'), 'verify_peer' => env('NEO4J_SSL_VERIFY_PEER', true), ], 'connection' => [ 'timeout' => env('NEO4J_CONNECTION_TIMEOUT', 30), 'max_pool_size' => env('NEO4J_MAX_POOL_SIZE', 100), ], 'transaction' => [ 'timeout' => env('NEO4J_TRANSACTION_TIMEOUT', 30), ], ],
Usage
Using Laravel's DB Facade
use Illuminate\Support\Facades\DB; // Basic query $result = DB::connection('neo4j')->select('MATCH (n) RETURN n'); // With parameters $result = DB::connection('neo4j')->select(<<<'CYPHER' MATCH (m:Movie {title: $title}) RETURN m CYPHER, ['title' => 'The Matrix']); // Transactions DB::connection('neo4j')->beginTransaction(); try { // Your queries here DB::connection('neo4j')->commit(); } catch (\Exception $e) { DB::connection('neo4j')->rollBack(); throw $e; }
Using Neo4j Client Interface
use Laudis\Neo4j\Contracts\SessionInterface; class YourController extends Controller { public function index(SessionInterface $session) { $result = $session->run(<<<'CYPHER' MATCH (n) RETURN n CYPHER); return response()->json($result->toArray()); } }
Example: Movie Management
// Create a movie $result = DB::connection('neo4j')->statement(<<<'CYPHER' CREATE (m:Movie { title: $title, released: $released, tagline: $tagline, created_at: datetime() }) RETURN m CYPHER, [ 'title' => 'The Matrix', 'released' => 1999, 'tagline' => 'Welcome to the Real World' ]); // Add an actor to a movie $result = DB::connection('neo4j')->select(<<<'CYPHER' MATCH (m:Movie {title: $movieTitle}) MERGE (a:Person {name: $actorName}) MERGE (a)-[r:ACTED_IN]->(m) SET r.roles = $roles RETURN m, a, r CYPHER, [ 'movieTitle' => 'The Matrix', 'actorName' => 'Keanu Reeves', 'roles' => ['Neo'] ]); // Find similar movies $result = DB::connection('neo4j')->select(<<<'CYPHER' MATCH (m:Movie {title: $title})<-[:ACTED_IN]-(a:Person)-[:ACTED_IN]->(other:Movie) WHERE m <> other WITH other, count(distinct a) as commonActors RETURN other, commonActors ORDER BY commonActors DESC LIMIT 5 CYPHER, ['title' => 'The Matrix']);
Example: User Management
// Create a user $result = $session->run(<<<'CYPHER' CREATE (u:User { name: $name, email: $email, created_at: datetime() }) RETURN u CYPHER, [ 'name' => 'John Doe', 'email' => 'john@example.com' ]); // Update a user $result = $session->run(<<<'CYPHER' MATCH (u:User {email: $email}) SET u.name = $name, u.updated_at = datetime() RETURN u CYPHER, [ 'email' => 'john@example.com', 'name' => 'John Smith' ]);
Features
- Seamless integration with Laravel's database layer
- Support for both DB Facade and Neo4j Client Interface
- Transaction support
- Parameterized queries
- SSL configuration options
- Connection pooling
- Timeout settings for connections and transactions
License
This package is open-sourced software licensed under the MIT license.