Querying with Cypher

Goals
This guide explains the basic concepts of Cypher, Neo4j’s graph query language. You should be able to read and understand Cypher queries after finishing this guide.
Prerequisites
You should be familiar with graph database concepts and the property graph model.

Beginner

Cypher Keywords

Just like with most programming languages, there are a few words in Cypher reserved for specific actions in parts of a query. We need to be able to create, read, update, or delete data in Neo4j, and keywords help us accomplish that functionality. Let us look more in detail at two common keywords (more will be covered in upcoming guides).

MATCH

The MATCH keyword in Cypher is what searches for an existing node, relationship, label, property, or pattern in the database. If you are familiar with SQL, MATCH works pretty much like SELECT in SQL.

You can find all node labels in the database, search for a particular node, find all the nodes with a particular relationship, look for patterns of nodes and relationships, and much more using MATCH.

RETURN

The RETURN keyword in Cypher specifies what values or results you might want to return from a Cypher query. You can tell Cypher to return nodes, relationships, node and relationship properties, or patterns in your query results. RETURN is not required when doing write procedures, but is needed for reads.

The node and relationship variables we discussed earlier become important when using RETURN. In order to bring back nodes, relationships, properties, or patterns, you need to have variables specified in your MATCH clause for the data you want to return.

Cypher Examples

Let us look at some examples of the syntax we have learned so far using MATCH and RETURN keywords. Each example will start with an explanation of what we are trying to achieve and have an image below of the results of the query run in Neo4j Browser.

  • Example 1: Find the labeled Person nodes in the graph. Note that we must use a variable like p for the Person node if we want retrieve the node in the RETURN clause.

MATCH (p:Person)
RETURN p
LIMIT 1
  • Example 2: Find Person nodes in the graph that have a name of 'Tom Hanks'. Remember that we can name our variable anything we want, as long as we reference that same name later.

MATCH (tom:Person {name: 'Tom Hanks'})
RETURN tom
  • Example 3: Find which `Movie`s Tom Hanks has directed.

Explanation: we know we need to find Tom Hanks' Person node, and we need to find the Movie nodes he is connected to. To do that, we need to follow the DIRECTED relationship from Tom Hanks' Person node to the Movie node. We have also specified a label of Movie so that the query will only look at nodes with that label. Since we only care about returning the company in this query, we need to give that node a variable (movie) but do not need to give variables for the Person node or WORKS_FOR relationship.

MATCH (:Person {name: 'Tom Hanks'})-[:DIRECTED]->(movie:Movie)
RETURN movie
  • Example 4: Find which Movie Tom Hanks has directed, but this time, return only the title of the movie.

Explanation: this query is very similar to Example 3. Example 3 returned the entire Movie node with all its properties. For this example, we still need to find Tom’s movies, but now we only care about their titles. We will need to access the node’s title property using the syntax variable.property to return the name value.

MATCH (:Person {name: 'Tom Hanks'})-[:DIRECTED]->(movie:Movie)
RETURN movie.title

Aliasing Return Values

Not all properties are simple like our movie.title example above. Some properties have poor names due to property length, multi-word descriptions, developer jargon, and other shortcuts. These naming conventions can be difficult to read, especially if they end up on reports and other user-facing interfaces.

Poorly-named Properties
//poorly-named property
MATCH (tom:Person {name:'Tom Hanks'})-[rel:DIRECTED]-(movie:Movie)
RETURN tom.name, tom.born, movie.title, movie.released

Just like with SQL, you can rename return results by using the AS keyword and aliasing the property with a cleaner name. We can look at a mocked-up example to list a customer’s orders and the number of items in the order.

Cleaner Results with aliasing
//cleaner printed results with aliasing
MATCH (tom:Person {name:'Tom Hanks'})-[rel:DIRECTED]-(movie:Movie)
RETURN tom.name AS name, tom.born AS `Year Born`, movie.title AS title, movie.released AS `Year Released`

You can specify return aliases that have spaces by using the backtick character before and after the alias (movie.released AS Year Released). If you do not have an alias that contains spaces, then you do not need to use backticks.

Code Challenge

Now that you know the basics, use the parts below to build a cypher statement to to find the title and year of release for every :Movie that Tom Hanks has :DIRECTED. Click the parts to add them in order and once you are done, click Run Query to see whether you have got it right. You can click any part of the query inside the code block to remove it.

MATCH (p:Person {name: "Tom Hanks"})-[:DIRECTED]->(m:Movie) RETURN m.title, m.released

Next Steps

Now that you know how to write nodes, relationships, properties, and patterns in Cypher for reading existing data, you can begin exploring data that exists in a Neo4j database. We will look at more MATCH capabilities in an upcoming guide, as well as how to write Cypher for create, update, and delete operations with your data.

Resources

Are you struggling?
If you need help with any of the information contained on this page, you can reach out to other members of our community. You can ask questions in the Cypher category on the Neo4j Community Site.