Multiple MATCH Clauses

Using multiple MATCH clauses

Here is an example of a query that contains two explicit MATCH clauses:

cypher
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
WHERE m.year > 2000
MATCH (m)<-[:DIRECTED]-(d:Person)
RETURN a.name, m.title, d.name

This query:

  1. Retrieves the anchor nodes (movies released after the year 2000) and the set of actors for each movie.

  2. It then follows the :DIRECTED relationships to each Movie node to retrieve the director of each movie.

  3. It returns the triple of actor name, movie title, director name.

Notice that actors, movie titles, directors are repeated in the rows returned.

Using multiple patterns in the MATCH clause

An alternative to using multiple MATCH clauses is to specify multiple patterns:

cypher
MATCH (a:Person)-[:ACTED_IN]->(m:Movie),
      (m)<-[:DIRECTED]-(d:Person)
WHERE m.year > 2000
RETURN a.name, m.title, d.name

In this query, multiple patterns are specified. In the second pattern, the variable m is used from the first pattern.

In general, using a single MATCH clause will perform better than multiple MATCH clauses. This is because relationship uniqueness is enforced so there are fewer relationships traversed.

Using a single pattern

And finally, the same query can be written as follows:

cypher
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(d:Person)
WHERE m.year > 2000
RETURN a.name, m.title, d.name

In most cases, specifying a single pattern will yield the best performance.

The performance of your queries will depend greatly upon your data model and the size of the graph.

Optionally matching rows

Cypher has a clause that allows you to return rows that contain null values for some properties.

Here is an example of a query that we will start with:

cypher
MATCH (m:Movie) WHERE m.title = "Kiss Me Deadly"
MATCH (m)-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(rec:Movie)
MATCH (m)<-[:ACTED_IN]-(a:Actor)-[:ACTED_IN]->(rec)
RETURN rec.title, a.name

In this query:

  1. We find the movie node for Kiss Me Deadly.

  2. Then we find all movies, rec that are in the same genre as Kiss Me Deadly.

  3. Then we find the actors that acted in both rec and Kiss Me Deadly.

The result is one actor who acted in both Kiss Me Deadly and The Killers.

What if we wanted to expand the results returned to return all movies that are in the same genre, and the actor that acted in both movies.

OPTIONAL MATCH matches patterns with your graph, just like MATCH does. The difference is that if no matches are found, OPTIONAL MATCH will use nulls for missing parts of the pattern. OPTIONAL MATCH could be considered the Cypher equivalent of the outer join in SQL.

Here is how you specify OPTIONAL MATCH in Cypher:

cypher
MATCH (m:Movie) WHERE m.title = "Kiss Me Deadly"
MATCH (m)-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(rec:Movie)
OPTIONAL MATCH (m)<-[:ACTED_IN]-(a:Actor)-[:ACTED_IN]->(rec)
RETURN rec.title, a.name

This query returns rows where the pattern where an actor acted in both movies is optional and a null value is returned for any row that has no value. In general, and depending on your graph, an optional match will return more rows.

Check your understanding

1. Optionally matching a pattern

We want to return the names of all actors whose name begins with Tom and also the title of the movies they directed. If they did not direct the movie, then return a null value.

How would you complete this query?

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

cypher
MATCH (p:Person)
WHERE p.name STARTS WITH 'Tom'
/*select:OPTIONAL MATCH (p)-[:DIRECTED]->(m:Movie)*/
RETURN p.name, m.title
  • MATCH (p)-[:DIRECTED]→(m:Movie)) OPTIONALLY

  • OPTIONALLY MATCH (p)-[:DIRECTED]→(m:Movie)

  • OPTIONAL MATCH (p)-[:DIRECTED]→(m:Movie)

  • PARTIAL MATCH (p)-[:DIRECTED]→(m:Movie)

Hint

What type of Cypher MATCH clause do you use the expand the number of rows returned so that null values may be returned in the rows?

Solution

The correct answer is: OPTIONAL MATCH (p)-[:DIRECTED]→(m:Movie)`.

The other clauses are not valid Cypher clauses.

2. Optional matches

What value does OPTIONAL MATCH return if there is no value for a string property being returned in a row?

  • ❏ ""

  • ❏ " "

  • ✓ null

  • ❏ false

Hint

What special value do you set a property to if you want to remove it from a node or relationship?

Solution

The correct answer is null. When a property does not exist, its value us null. When you set a property value to null, you are essentially removing the property from the node or relationship.

An empty string, a string with a blank, or false are all considered valid property values.

Summary

In this lesson, you learned the difference between multiple match clauses and multiple match patterns in a query, as well as optional matches.

In the next challenge, you will have an opportunity to perform an optional match.