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.
composer require neo4j-php/neo4j-laravelAdd the following to your .env file:
DB_CONNECTION=neo4j
NEO4J_URL=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_password
NEO4J_DATABASE=neo4jEach 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_queriesAdd 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),
],
],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;
}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());
}
}// 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']);// 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'
]);- 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
This package is open-sourced software licensed under the MIT license.