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.

  • USE clause.

  • MATCH clause.

  • OPTIONAL MATCH clause.

  • WITH clause.

  • RETURN clause.

  • 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.

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.

The RETURN clause can use:

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

Write-Only Query Structure

[USE]
[CREATE]
[MERGE [ON CREATE ...] [ON MATCH ...]]
[WITH [ORDER BY] [SKIP] [LIMIT] [WHERE]]
[SET]
[DELETE]
[REMOVE]
[RETURN [ORDER BY] [SKIP] [LIMIT]]

Baseline for write operations.

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]]

Baseline for pattern search and write operations.

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.