Introduction
ArcadeDB provides native support for the Cypher query language through a new, high-performance implementation built from the ground up. This native OpenCypher module uses an ANTLR4-based parser with the official Cypher 2.5 grammar, providing excellent compatibility and performance.
|
Deprecation Notice: Legacy Cypher Implementation ArcadeDB includes two Cypher implementations:
The legacy To migrate: Simply change your query language from |
Key Features
The native OpenCypher implementation provides:
-
High Performance: Direct execution without Gremlin translation, comparable to native SQL
-
Full Read/Write Support: MATCH, CREATE, MERGE, SET, DELETE with automatic transaction handling
-
Advanced Pattern Matching: Variable-length paths with path modes (WALK, TRAIL, ACYCLIC), OPTIONAL MATCH, multiple MATCH clauses
-
Query Composition: UNION/UNION ALL for combining results, WITH for query chaining
-
Procedures and Profiling: CALL for invoking built-in procedures and custom functions, PROFILE for performance analysis
-
Rich Function Library: 23+ native Cypher functions plus bridge to 100+ ArcadeDB SQL functions
-
Cost-Based Optimizer: Intelligent query planning with index selection and join ordering
-
100% Test Coverage: Comprehensive test suite with 295+ passing tests
Using OpenCypher
To execute OpenCypher queries, use opencypher as the query language identifier.
From Java API:
ResultSet result = database.query("opencypher",
"MATCH (p:Person) WHERE p.age >= $minAge RETURN p.name, p.age ORDER BY p.age",
"minAge", 25);
Through Neo4j BOLT Protocol (v26.2.1+):
Connect using any Neo4j driver via the BOLT protocol:
Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("root", "password"));
Session session = driver.session(SessionConfig.forDatabase("mydatabase"));
Result result = session.run("MATCH (p:Person) WHERE p.age >= 25 RETURN p.name, p.age ORDER BY p.age");
Through PostgreSQL Driver:
Prefix your query with {opencypher}:
"{opencypher} MATCH (p:Person) WHERE p.age >= 25 RETURN p.name, p.age ORDER BY p.age"
Through HTTP/JSON API (GET - idempotent queries):
curl "http://localhost:2480/query/graph/opencypher/MATCH%20(p:Person)%20RETURN%20p"
Through HTTP/JSON API (POST - updates):
curl -X POST "http://localhost:2480/command/graph" \
-d "{'language': 'opencypher', 'command': 'CREATE (p:Person {name: \"Alice\", age: 30})'}"
Using Record IDs (RIDs)
You can use ArcadeDB’s RecordIDs (RID) in Cypher queries to start from a specific vertex. RIDs in Cypher are always strings, so they must be contained between single or double quotes.
MATCH (m:Movie)<-[a:ACTED_IN]-(p:Person) WHERE id(m) = '#1:0' RETURN *
Parameters
OpenCypher supports parameterized queries using the $paramName syntax:
MATCH (p:Person) WHERE p.age >= $minAge AND p.city = $city RETURN p
Parameters are passed as key-value pairs after the query string:
ResultSet result = database.query("opencypher",
"MATCH (p:Person) WHERE p.age >= $minAge RETURN p",
"minAge", 25);
Automatic Transaction Handling
All write operations (CREATE, SET, DELETE, MERGE) automatically handle transactions:
-
If no transaction is active, the operation creates, executes, and commits its own transaction
-
If a transaction is already active, the operation reuses it without committing
-
Proper rollback on errors for self-managed transactions
// Automatic transaction - commits automatically
database.command("opencypher", "CREATE (n:Person {name: 'Alice'})");
// Manual transaction - you control commit/rollback
database.transaction(() -> {
database.command("opencypher", "CREATE (a:Person {name: 'Alice'})");
database.command("opencypher", "CREATE (b:Person {name: 'Bob'})");
database.command("opencypher", "MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS]->(b)");
// Commits when lambda completes successfully
});
Performance Considerations
The native OpenCypher implementation includes a cost-based query optimizer that:
-
Automatically selects optimal indexes for node lookups
-
Uses range index scans for inequality predicates (
>,<,>=,⇐) -
Optimizes join order based on cardinality estimation
-
Detects bounded patterns for efficient relationship traversal
For best performance:
-
Create indexes on frequently queried properties
-
Use labeled nodes in MATCH patterns for faster type filtering
-
Prefer specific property constraints over full scans
-
Use parameters for queries executed multiple times (enables query plan caching)
Comparison with Legacy Cypher
| Feature | opencypher (NEW) |
cypher (DEPRECATED) |
|---|---|---|
Execution |
Native, direct |
Gremlin translation |
Performance |
Fast (comparable to SQL) |
Slow (up to 20x slower) |
Write Operations |
Full support |
Limited support |
OPTIONAL MATCH |
Supported |
Partial support |
Variable-length Paths |
Supported |
Limited |
UNION / UNION ALL |
Supported |
Not supported |
CALL Procedures |
Supported |
Not supported |
PROFILE |
Supported |
Not supported |
Aggregations |
Full support |
Limited |
Functions |
100+ functions |
Limited |
Transaction Handling |
Automatic |
Manual |
Active Development |
Yes |
No (abandoned upstream) |