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.
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:
// 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 :
.
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:
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.
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
.
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.
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.
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.
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.