Introduction to Cypher

What is Cypher?

Cypher is a query language designed for graphs.

The whiteboard model of our domain entities is stored in the database as a graph. When we draw a graph on the whiteboard, we represent entities as circles connected together using arrows. In this example, the entities are people and movies. We have Person and Movie nodes in our graph.

Whiteboard-image

Just as we would draw circles and arrows on a whiteboard, we write out the pattern in Cypher:

  • Nodes are represented by parentheses ().

  • We use a colon to signify the label(s), for example (:Person).

  • Relationships between nodes are written with two dashes, for example (:Person)--(:Movie).

  • The direction of a relationship is indicated using a greater than or less than symbol < or > , for example (:Person)-→(:Movie).

  • The type of the relationship is written using the square brackets between the two dashes: [ and ], for example [:ACTED_IN]

  • Properties drawn in a speech bubble are specified in a JSON like syntax.

    • Properties in Neo4j are key/value pairs, for example {name: 'Tom Hanks'}.

For example, a Cypher pattern in the graph could be:

Partial
// example Cypher pattern
(m:Movie {title: 'Cloud Atlas'})<-[:ACTED_IN]-(p:Person)

The two node types in this pattern are Movie and Person. The Person nodes have a directed ACTED_IN relationship to Movie nodes. The specific Movie node in this pattern is filtered by the title property with a value of Cloud Atlas. So this pattern represents all people in the graph who acted in the movie, Cloud Atlas.

How Cypher works

Cypher works by matching patterns in the data. We retrieve data from the graph using the MATCH keyword. You can think of the MATCH clause as similar to the FROM clause in an SQL statement.

For example, if we want to find a Person in the graph, we would MATCH a pattern of a single node with a label of :Person - prefixed with a colon :.

Partial
MATCH (:Person)
// incomplete MATCH clause because we need to return something

Suppose we want to retrieve all Person nodes from the graph. We can assign a variable by placing a value before the colon. Let’s use the variable p. Now that p represents all Person nodes retrieved from the graph, we can return them using the RETURN clause.

Run this Cypher code:

Click the Run in Sandbox button to the top right of the code sample to open the Sandbox to the right and run the query.
cypher
MATCH (p:Person)
RETURN p

This query returns all nodes in the graph with the Person label. You can view the results returned using the graph view or the table view. When you select the table view, you can also see the properties for the nodes returned.

Now, say we want to find the node which represents the Person who’s name is Tom Hanks. Our Person nodes all have a name property. We can use the braces {..} to specify the key/value pair of name and Tom Hanks as the filter. As Tom Hanks is a string, we will need to place it inside single or double quotes.

cypher
MATCH (p:Person {name: 'Tom Hanks'})
RETURN p

This query returns a single node that represents Tom Hanks. In the graph view of Neo4j Browser, the node is visualized as a bubble. You can also view the results returned in table view where you can view the properties of the node.

In our Cypher statement, we can access properties using a dot notation. For example, to return the name property value using its property key p.name.

cypher
MATCH (p:Person {name: 'Tom Hanks'})
RETURN  p.born

This query returns the value of the born property of the Tom Hanks node.

In Cypher, labels, property keys, and variables are case-sensitive. Cypher keywords are not case-sensitive.

Neo4j best practices include:

  • Name labels using CamelCase.

  • Name property keys and variables using camelCase.

  • Use UPPERCASE for Cypher keywords.

Another way that you can filter queries is by using the WHERE clause, rather than specifying the property value inline with braces.

This query returns the same data as the previous query.

cypher
MATCH (p:Person)
WHERE p.name = 'Tom Hanks'
RETURN p.born

As you gain more experience with Cypher, you will find that using WHERE to filter your queries is very powerful because you can add more logic to your WHERE clause. Here is an example where we filter by two values for name.

cypher
MATCH (p:Person)
WHERE p.name = 'Tom Hanks' OR p.name = 'Rita Wilson'
RETURN p.name, p.born

This query returns two names and their associated birth years.

Check your understanding

1. Read data

Which Cypher clause do you use to read data from Neo4j?

  • FIND

  • SELECT

  • MATCH

  • FROM

Hint

This Cypher clause is typically used to return data to the client using a RETURN clause.

Solution

You use the MATCH clause to define the pattern in the graph that you would like to search for.

2. Filtering

What Cypher keyword can you use to filter the nodes retrieved during the execution of a MATCH clause?

  • FILTER

  • SELECT

  • WHERE

  • FROM

Hint

You specify this keyword after MATCH before results are returned to the client.

Solution

Just like SQL, you use the WHERE clause to filter results in Cypher.

3. Retrieving a property

We want to know what the tagline is for the movie, The Matrix. Use the dropdown below complete the query.

Once you have selected your option, click the Check Results query button to continue.

cypher
MATCH (m:Movie)
/*select:WHERE m.title = 'The Matrix'*/
RETURN m.tagline
  • SELECT m.title = 'The Matrix'

  • HAVING {title: 'The Matrix'}

  • WHERE m {title: 'The Matrix'}

  • WHERE m.title = 'The Matrix'

Hint

You use this clause to filter data after a MATCH clause. This is an alternative to filtering the data inline.

Solution

The :Movie node is aliased with m, and we are looking for any nodes with the title property equal to The Matrix.

Therefore, the answer will be WHERE m.title = 'The Matrix'.

Summary

In this lesson, you learned how write queries to retrieve nodes from the graph. In the next challenge, you will demonstrate your skills to retrieve a node from the graph.