Cypher Cheat Sheet
Read Query
Read Query Structure
[USE]
[MATCH [SEARCH] [WHERE]]
[OPTIONAL MATCH [SEARCH] [WHERE]]
[WITH [ORDER BY] [SKIP] [LIMIT] [WHERE]]
RETURN [ORDER BY] [SKIP] [LIMIT]
Baseline for pattern search operations.
-
USEclause. -
MATCHclause. -
OPTIONAL MATCHclause. -
WITHclause. -
RETURNclause. -
Cypher® keywords are not case-sensitive.
-
Cypher is case-sensitive for variables.
MATCH
MATCH (n)
RETURN n
Match all nodes and return all nodes.
MATCH (movie:Movie)
RETURN movie.title
Find all nodes with the Movie label.
MATCH (:Person {name: 'Oliver Stone'})-[r]->()
RETURN type(r) AS relType
Find the types of an aliased relationship.
MATCH (:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor:Person)
RETURN actor.name AS actor
Relationship pattern filtering on the ACTED_IN relationship type.
MATCH path = ()-[:ACTED_IN]->(movie:Movie)
RETURN path
Bind a path pattern to a path variable, and return the path pattern.
MATCH (movie:$($label))
RETURN movie.title AS movieTitle
Node labels and relationship types can be referenced dynamically in expressions, parameters, and variables.
The expression must evaluate to a STRING NOT NULL | LIST<STRING NOT NULL> NOT NULL value.
CALL db.relationshipTypes()
YIELD relationshipType
MATCH ()-[r:$(relationshipType)]->()
RETURN relationshipType, count(r) AS relationshipCount
Match nodes dynamically using a variable.
OPTIONAL MATCH
MATCH (p:Person {name: 'Martin Sheen'})
OPTIONAL MATCH (p)-[r:DIRECTED]->()
RETURN p.name, r
Use MATCH to find entities that must be present in the pattern.
Use OPTIONAL MATCH to find entities that may not be present in the pattern.
OPTIONAL MATCH returns null for empty rows.
WHERE
MATCH (n)
WHERE n:Swedish
RETURN n.name AS name
WHERE used to filter on node labels.
MATCH (n:Person)
WHERE n.age < 35
RETURN n.name AS name, n.age AS age
WHERE used to filter on node properties.
MATCH (:Person {name:'Andy'})-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f.name AS oldFriend
WHERE used to filter on relationship properties.
MATCH (n)
WHERE n:$($label)
RETURN labels(n) AS labels
MATCH (n:Person)
WHERE n[$propname] > 40
RETURN n.name AS name, n.age AS age
To filter on a property using a dynamically computed name, use square brackets [].
WITH 35 AS minAge
MATCH (a:Person WHERE a.name = 'Andy')-[:KNOWS]->(b:Person WHERE b.age > minAge)
RETURN b.name AS name
WHERE used inside a fixed-length pattern.
MATCH (a:Person {name: 'Andy'})
RETURN [(a)-->(b WHERE b:Person) | b.name] AS friends
WHERE can appear inside a pattern comprehension.
MATCH p = (a:Person {name: "Andy"})-[r:KNOWS WHERE r.since < 2011]->{1,4}(:Person)
RETURN [n IN nodes(p) | n.name] AS paths
WHERE can be used to filter variable-length patterns.
SEARCH
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title
SEARCH is used to query vector indexes, and filters the result based on approximate nearest neighbor (ANN) vector search.
It can can appear in a MATCH or OPTIONAL MATCH clause.
MATCH ()-[r]->()
SEARCH r IN (
VECTOR INDEX `relVectorIndexName`
FOR [1, 2, 3]
WHERE r.additionalProp > 10
LIMIT 5
) SCORE AS myScore
RETURN r, myScore
SEARCH can also be used for relationships.
SEARCH can include an optional WHERE subclause for in-index filtering and an optional SCORE subcluase to return similarity scores.
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR [1, 2, 3]
LIMIT 4
)
RETURN movie.title AS title
Query a vector index using a list literal as the query vector.
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR $snowWhiteEmbedding
LIMIT 4
)
RETURN movie.title AS title
Query a vector index using a vector supplied as a parameter.
MATCH (snowWhite:Movie {title: 'Snow White'})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.embedding
LIMIT 4
)
RETURN movie.title AS title
Query a vector index using an embedding property from another node as the query vector.
MATCH (snowWhite:Movie {title: 'Snow White'})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.embedding
LIMIT 4
) SCORE AS similarityScore
RETURN movie.title AS title, similarityScore
Return the similarity score for each result by binding it with SCORE AS.
MATCH (movie:Movie&Favorite)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title
Apply an additional label predicate to the nodes returned by the vector search.
MATCH (movie:Movie {releaseDate: date('2013-11-10')})
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title
Apply an additional property predicate to the nodes returned by the vector search.
MATCH (movie:Movie)
WHERE movie.releaseDate > date('1990')
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year
Filter vector-search results with a WHERE clause before the SEARCH subclause.
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
LIMIT 4
)
WHERE movie.releaseDate > date('1990')
RETURN movie.title AS title, movie.releaseDate.year AS year
Filter vector-search results with a WHERE clause after the SEARCH subclause.
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.releaseDate > date('1990')
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year
Use an in-index WHERE filter to return the requested number of matching vector-search results.
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.releaseDate > date('1990')
LIMIT 4
)
WHERE movie.rating > 7.5
RETURN movie.title AS title, movie.releaseDate.year AS year, movie.rating AS rating
Combine an in-index vector-search filter with a post-filtering WHERE clause.
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.releaseDate > date('1948') AND date('2010') > movie.releaseDate
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year
Use multiple range predicates on the same property in a vector-search filter.
MATCH (snowWhite:Movie {title:"Snow White"})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.embedding
WHERE movie.releaseDate < date('2000') AND movie.rating >= snowWhite.rating
LIMIT 4
)
RETURN movie.title AS title, movie.releaseDate.year AS year, movie.rating AS rating
Use a vector-search filter with predicates on separate properties.
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR vector([1, 2, 3], 3, INTEGER)
WHERE movie.rating IN [7.4, 7.7, 8.5]
LIMIT 4
)
RETURN movie.title AS title, movie.rating AS rating
Use the IN operator in a vector-search filter to match one of several values.
MATCH (snowWhite:Movie {title: 'Snow White'})
MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.prop
LIMIT 4
)
RETURN movie.title AS title
Show that a SEARCH query in a MATCH returns no rows when its query vector is null.
MATCH (snowWhite:Movie {title: 'Snow White'})
OPTIONAL MATCH (movie:Movie)
SEARCH movie IN (
VECTOR INDEX moviePlots
FOR snowWhite.prop
LIMIT 4
)
RETURN movie.title AS title
Show that an OPTIONAL MATCH returns a null result when its query vector is null.
MATCH (node)
SEARCH node IN (
FULLTEXT INDEX namesAndTeams
FOR "nils"
LIMIT 5
)
SCORE AS score
RETURN node.name, score
Query a full-text node index for a search string and return each node’s score.
MATCH ()-[relationship]->()
SEARCH relationship IN (
FULLTEXT INDEX communications
FOR "meeting"
LIMIT 5
)
SCORE AS score
RETURN type(relationship), relationship.message, score
Query a full-text relationship index for a search string and return each relationship’s score.
MATCH (node)
SEARCH node IN (
FULLTEXT INDEX namesAndTeams
FOR '"Nils-Erik"'
LIMIT 5
)
SCORE AS score
RETURN node.name, score
Use quotation marks in the query string to search for an exact phrase.
MATCH (node)
SEARCH node IN (
FULLTEXT INDEX namesAndTeams
FOR 'nils AND kernel'
LIMIT 5
)
SCORE AS score
RETURN node.name, node.team, score
Use boolean operators to combine terms in a full-text query.
MATCH (node)
SEARCH node IN (
FULLTEXT INDEX namesAndTeams
FOR 'team:"Operations"'
LIMIT 5
)
SCORE AS score
RETURN node.name, node.team, score
Limit a full-text query to a specific indexed property by prefixing the property name.
MATCH (node)
SEARCH node IN (
FULLTEXT INDEX reviews
FOR 'late'
LIMIT 5
)
SCORE AS score
RETURN node.name, node.peerReviews, score
Query a full-text index whose indexed property contains a list of strings.
MATCH ()-[relationship]->()
SEARCH relationship IN (
FULLTEXT INDEX communications
FOR "reportedly" WITH ANALYZER "english"
LIMIT 5
)
SCORE AS score
RETURN type(relationship), relationship.message, score
Select the english analyzer for a full-text search with WITH ANALYZER.
FILTER
MATCH (n:Person)
FILTER n.age < 35
RETURN n.name AS name, n.age AS age
FILTER is used to add filters to queries, similar to Cypher’s WHERE.
Unlike WHERE, FILTER is not a subclause, which means it can be used independently of the MATCH, OPTIONAL MATCH, and WITH clauses, but not within them.
MATCH (n:Person)
FILTER n[$propname] > 40
RETURN n.name AS name, n.age AS age
FILTER on dynamic properties.
LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
FILTER row.Id IS NOT NULL
MERGE (c:Company {id: row.Id})
FILTER can be used as a substitute for the WITH * WHERE <predicate> constructs in Cypher.
RETURN
MATCH (p:Person {name: 'Keanu Reeves'})
RETURN p
Return a node.
MATCH (p:Person {name: 'Keanu Reeves'})-[r:ACTED_IN]->(m)
RETURN type(r)
Return relationship types.
MATCH (p:Person {name: 'Keanu Reeves'})
RETURN p.bornIn
Return a specific property.
MATCH p = (keanu:Person {name: 'Keanu Reeves'})-[r]->(m)
RETURN *
To return all nodes, relationships and paths found in a query, use the * symbol.
MATCH (p:Person {name: 'Keanu Reeves'})
RETURN p.nationality AS citizenship
Names of returned columns can be aliased using the AS operator.
MATCH (p:Person {name: 'Keanu Reeves'})-->(m)
RETURN DISTINCT m
DISTINCT retrieves unique rows for the returned columns.
WITH
MATCH (c:Customer)-[:BUYS]->(:Product {name: 'Chocolate'})
WITH c AS customers
RETURN customers.firstName AS chocolateCustomers
WITH can be used in combination with the AS keyword to bind new variables which can then be passed to subsequent clauses.
Any variables not explicitly referenced by WITH (or carried over by WITH *) are dropped from the scope of the query.
MATCH (supplier:Supplier)-[r]->(product:Product)
WITH *
RETURN supplier.name AS company,
type(r) AS relType,
product.name AS product
Use the wildcard * to carry over all variables that are in scope.
WITH 11 AS x
CALL (x) {
UNWIND [2, 3] AS y
WITH y
RETURN x*y AS a
}
RETURN x, a
WITH cannot de-scope variables imported to a CALL subquery, because variables imported to a subquery are considered global to its inner scope.
MATCH (customer:Customer)-[:BUYS]->(chocolate:Product {name: 'Chocolate'})
WITH customer.firstName || ' ' || customer.lastName AS customerFullName,
chocolate.price * (1 - customer.discount) AS chocolateNetPrice
RETURN customerFullName,
chocolateNetPrice
WITH can be used to assign the values of expressions to variables.
MATCH (p:Product)
WITH p, p.price >= 500 AS isExpensive
WITH p, isExpensive, NOT isExpensive AS isAffordable
WITH p, isExpensive, isAffordable,
CASE
WHEN isExpensive THEN 'High-end'
ELSE 'Budget'
END AS discountCategory
RETURN p.name AS product,
p.price AS price,
isAffordable,
discountCategory
ORDER BY price
WITH can be used to chain expressions.
MATCH (c:Customer)-[:BUYS]->(p:Product)
WITH c.firstName AS customer,
sum(p.price) AS totalSpent,
collect(p.name) AS productsBought
RETURN customer,
totalSpent,
productsBought
ORDER BY totalSpent DESC
WITH can be used to perform aggregations and bind the results to new variables.
MATCH (c:Customer)
WITH DISTINCT c.discount AS discountRates
RETURN discountRates
ORDER BY discountRates
WITH can be used to remove duplicate values from the result set if appended with the modifier DISTINCT.
MATCH (c:Customer)-[:BUYS]->(p:Product)
WITH c,
sum(p.price) AS totalSpent
ORDER BY totalSpent DESC
LIMIT 3
SET c.topSpender = true
RETURN c.firstName AS customer,
totalSpent,
c.topSpender AS topSpender
WITH can order and paginate results if used together with the ORDER BY, LIMIT, and SKIP subclauses.
MATCH (s:Supplier)-[:SUPPLIES]->(p:Product)<-[:BUYS]-(c:Customer)
WITH s,
sum(p.price) AS totalSales,
count(DISTINCT c) AS uniqueCustomers
WHERE totalSales > 1000
RETURN s.name AS supplier,
totalSales,
uniqueCustomers
WITH can be followed by the WHERE subclause to filter results.
LET
MATCH (s:Supplier)-[:SUPPLIES]->(p:Product)
LET supplier = s.name, product = p.name
RETURN supplier, product
LET is used to bind variables to the results of expressions.
MATCH (p:Product)
LET isExpensive = p.price >= 500
LET isAffordable = NOT isExpensive
LET discountCategory = CASE
WHEN isExpensive THEN 'High-end'
ELSE 'Budget'
END
RETURN p.name AS product, p.price AS price, isAffordable, discountCategory
ORDER BY price
LET can be used to chain expressions.
Write query
Read-Write Query Structure
[USE]
[MATCH [WHERE]]
[OPTIONAL MATCH [WHERE]]
[WITH [ORDER BY] [SKIP] [LIMIT] [WHERE]]
[CREATE]
[MERGE [ON CREATE ...] [ON MATCH ...]]
[WITH [ORDER BY] [SKIP] [LIMIT] [WHERE]]
[SET]
[DELETE]
[REMOVE]
[RETURN [ORDER BY] [SKIP] [LIMIT]]
CREATE
CREATE (charlie:Person:Actor {name: 'Charlie Sheen'}), (oliver:Person:Director {name: 'Oliver Stone'})
Create nodes. Multiple labels can be separated by colons or ampersands.
MATCH (charlie:Person {name: 'Charlie Sheen'}), (oliver:Person {name: 'Oliver Stone'})
CREATE (charlie)-[:ACTED_IN {role: 'Bud Fox'}]->(wallStreet:Movie {title: 'Wall Street'})<-[:DIRECTED]-(oliver)
Create relationships. Unlike nodes, relationships always need exactly one relationship type and a direction.