Fastest path to graph queries
Neo4j Cypher query language
Cypher is a declarative graph query language that is used by developers worldwide. Created by Neo4j, Cypher provides expressive and efficient queries for property graphs.
What is Cypher?
Overview
Visual, intuitive, and powerful graph data query language
Cypher’s easy-to-learn pattern constructs make it accessible for developers, data scientists, and those with limited query language experience. Users can simply express what data to retrieve while the underlying engine completes the task – eliminating the need for technical implementation knowledge.
Benefits
Benefits of Neo4j Cypher query language
The property graph data model is increasingly popular across a wide variety of application domains, with growing adoption in multiple products and projects. Cypher is the most established and intuitive query language to learn for working with property graphs.
Easy to learn
A Cypher statement is quite compact. It expresses references between nodes as visual patterns, which makes them easy to understand. Cypher has a low-learning curve, which helps users quickly write expressive, intuitive queries to retrieve results faster. Find a Cypher learning track in our GraphAcademy.
Visual and logical
Match patterns of nodes and relationships in the graph using ASCII-Art syntax. These patterns map directly to the domain model drawn in diagrams or on whiteboards. As a result, there is no impedance mismatch between the model, the database, and the query language.
Secure, reliable, and data-rich
Cypher is well-suited for application development and data analytics. It reduces repeated calls to the database and expresses use-case specific data needs in single, compact queries. Neo4j drivers use reactive programming approaches that save cloud computing resources and manage back-pressure.
Open and flexible
Cypher is an open data query language, based on the openCypher initiative. It is extensible with user-defined functions and procedures. The Neo4j implementation of the Cypher parser, planner, and runtime is open source.
Experiment with Cypher in AuraDB Free, our cloud-based graph database. Try Cypher
No more complex joins
Cypher is a graph-optimized query language that understands, and takes advantage of, data connections. It follows connections – in any direction – to reveal previously unknown relationships and clusters. Cypher queries are much easier to write than massive SQL joins. Compare this Cypher query to its equivalent in SQL.
Cypher
MATCH (p:Product)-[:CATEGORY]->(l:ProductCategory)-[:PARENT*0..]->(:ProductCategory {name:"Dairy Products"})
RETURN p.name
SQL
SELECT p.ProductName FROM Product AS p JOIN ProductCategory pc ON (p.CategoryID = pc.CategoryID AND pc.CategoryName = "Dairy Products") JOIN ProductCategory pc1 ON (p.CategoryID = pc1.CategoryID) JOIN ProductCategory pc2 ON (pc1.ParentID = pc2.CategoryID AND pc2.CategoryName = "Dairy Products") JOIN ProductCategory pc3 ON (p.CategoryID = pc3.CategoryID) JOIN ProductCategory pc4 ON (pc3.ParentID = pc4.CategoryID) JOIN ProductCategory pc5 ON (pc4.ParentID = pc5.CategoryID AND pc5.CategoryName = "Dairy Products");
Neo4j and Cypher under the hood
Cypher is an expressive language with advanced graph patterns and collection support. Under the hood, the cypher processing pipeline first parses the query if not in cache, then goes through semantic verification and rewriting of the AST, followed by finding the cheapest execution plan (logical and physical) for all the operations using available planners, all the way to query execution.
Run your own Cypher query right now
Following is an example that demonstrates how easy it is to use Cypher using two simple datasets, TMDB (Movies) and Northwind (Retail). (You can also install these datasets directly into your Neo4j database by running :play movies and :play northwind in the Neo4j Browser and execute the load statements.) This example also shows how much easier it is to use Cypher compared to SQL.
Follow a chain of relationships to an arbitrary depth and return the full path.
Cypher
MATCH path =
(p:Product {productName:'Pavlova'})-[:PART_OF*]->(root:Category)
RETURN path
Find the shortest connection between two entities, here the “Bacon-Path.”
Cypher
MATCH (bacon:Person {name:'Kevin Bacon'})
MATCH path = shortestPath(
(:Person {name:'Meg Ryan'})-[:ACTED_IN*..10]-(bacon))
RETURN path, length(path);
In Cypher, reads and writes can be combined in a single statement, which allows the full power of the language to select data to update and to return updated data directly to the user.
Cypher
// read
MATCH (m:Movie {title:'Matrix Resurrections'})
// possibly write
MERGE (u:User {name:'Emil Eifrem'})
// possibly write
MERGE (u)-[r:RATED]->(m)
// write
SET r.stars = 5
WITH *
MATCH (m)<-[:ACTED_IN]-(a:Person)
// read & return
RETURN u, m, r, collect(a)
With Cypher you can use query pipelining with WITH and implicit grouping to simplify aggregations and multi-part analytics queries.
Cypher
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) // in-between aggregation, only passing on declared fields WITH a, count(m) as movies // with filter on the aggregated value WHERE movies > 2 // next query part MATCH (a)-[:DIRECTED]->(m) // aggregation at the end by a.name RETURN a.name, collect(m.title) as movies, count(*) as count ORDER BY count DESC LIMIT 5;
Load CSV, JSON and other data types from other data sources.
Cypher
WITH "https://data.neo4j.com/importing/ratings.csv" AS url
LOAD CSV WITH HEADERS FROM url AS row
MATCH (m:Movie {id:row.movieId})
MERGE (u:User {userId:row.userId})
ON CREATE SET u.name = row.name
MERGE (u)-[r:RATED]->(m)
SET r.rating = toFloat(row.rating)
SET r.timestamp = toInteger(row.timestamp);
Cypher
MATCH path =
(p:Product {productName:'Pavlova'})-[:PART_OF*]->(root:Category)
RETURN path
Find the shortest connection between two entities, here the “Bacon-Path.”
Cypher
MATCH (bacon:Person {name:'Kevin Bacon'})
MATCH path = shortestPath(
(:Person {name:'Meg Ryan'})-[:ACTED_IN*..10]-(bacon))
RETURN path, length(path);
Cypher
// read
MATCH (m:Movie {title:'Matrix Resurrections'})
// possibly write
MERGE (u:User {name:'Emil Eifrem'})
// possibly write
MERGE (u)-[r:RATED]->(m)
// write
SET r.stars = 5
WITH *
MATCH (m)<-[:ACTED_IN]-(a:Person)
// read & return
RETURN u, m, r, collect(a)
Cypher
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) // in-between aggregation, only passing on declared fields WITH a, count(m) as movies // with filter on the aggregated value WHERE movies > 2 // next query part MATCH (a)-[:DIRECTED]->(m) // aggregation at the end by a.name RETURN a.name, collect(m.title) as movies, count(*) as count ORDER BY count DESC LIMIT 5;
Cypher
WITH "https://data.neo4j.com/importing/ratings.csv" AS url
LOAD CSV WITH HEADERS FROM url AS row
MATCH (m:Movie {id:row.movieId})
MERGE (u:User {userId:row.userId})
ON CREATE SET u.name = row.name
MERGE (u)-[r:RATED]->(m)
SET r.rating = toFloat(row.rating)
SET r.timestamp = toInteger(row.timestamp);
Learn more about these features or run :play cypher-vs-sql in the Neo4j Browser.
Ready to dig deeper into Cypher?
Sign up for AuraDB Free and get started now.