Developer Guides Getting Started Getting Started What is a Graph Database? Intro to Graph DBs Video Series Concepts: RDBMS to Graph Concepts: NoSQL to Graph Getting Started Resources Neo4j Graph Platform Graph Platform Overview Neo4j Desktop Intro Neo4j Browser Intro… Read more →
Filtering Query Results
Building on the Cypher Basics I and II guides, this guide continues with additional concepts of Cypher for filtering and query criteria. Upon finishing this guide, you should be able to filter results on properties and patterns for ranges and other expanded searches.
You should be familiar with graph database concepts and the property graph model. This guide is a continuation of the Cypher Basics I and Cypher Basics II sections. You should be familiar with those concepts before walking through this guide.
The Cypher you have written and learned so far has only tested properties with specific values. It has operated on the fact that those values must exist or no results will be returned.
However, most of the time, developers are not querying for a narrow value and need more flexibility in retrieving data for ranges, partial values, or other criteria.
Cypher provides this capability through the common
We will look at examples of different ways to apply the
WHERE clause to retrieve various results, but many will be similar to standard uses of the same clause in other programming languages.
All of our examples will continue with the graph example we have been using in the previous guides, but include some more data for some of our later queries. Below is an image of the new graph.
We have added more
Person nodes (blue) who
Company nodes (red) and
Each person could also have multiple
IS_FRIENDS_WITH relationships to other people.
This gives us a network of people, the companies they work for, and the technologies they like.
Cypher is designed to be flexible and easy-to-learn, so there is often more than one way to write syntax.
This is also the case with the
You can write a query that looks for specific values, just like we have been doing in the last few guides, but you can also use the
WHERE clause in the same manner.
Both queries execute with the same performance, so which way you write them is entirely up to your preference and comfort.
Below is a comparison of the syntax using our example from previous guides. Both queries will do the same thing and return the same results.
Sometimes, you may want to return results that do not match a property value.
In this case, you need to search for where value is not something using
There are a few types of these comparisons that you can run in Cypher with the standard boolean operators
To show a comparison using
NOT, we can write the opposite of the query example just above.
There are frequently queries where you want to look for data within a certain range. Date or number ranges can be used to check for events within a certain timeline, age values, or other uses.
The syntax for this criteria is very similar to SQL and other programming language logic structures for checking ranges of values. Let’s look at an example below.
You may only be interested if a property exists on a node or relationship. For instance, you might want to check which customers in your system have Twitter handles, so you can show relevant content. Or, you could check if the all of your employees have a start date property to verify which entities might need updated.
Remember: in Neo4j, a property only exists (is stored) if it has a value. A null property will not be stored. This ensures that only valuable, necessary information is retained for your nodes and relationships.
To write this type of existence check, you simply need to use the
WHERE clause and the
exists() method for that property.
The Cypher code is written in the block below.
Some scenarios require query syntax that matches on partial values or broad categories within a string. To do this kind of query, you need some flexibility and options for string matching and searches. Whether you are looking for a string that starts with, ends with, or includes a certain value, Cypher offers the ability to handle it performantly and easily.
There are a few keywords in Cypher used with the
WHERE clause to test string property values.
STARTS WITH keyword allows you check the value of a property that begins with the string you specify.
CONTAINS keyword, you can check if a specified string is part of a property value.
ENDS_WITH keyword checks the end of the property string for the value you specify.
An example of each is in the Cypher block below.
You can also use regular expressions to test the value of strings.
For example, you could look for all the
Person nodes that share a first name or you could find all the classes with a certain department code.
Let’s look at an example.
Just like in SQL and other languages, you can check if a property value is a value in a list.
IN keyword allows you to specify an array of values and validate a property’s contents against each one in the list.
Here is an example:
One thing that makes graph unique is its focus on relationships. Just as you can filter queries based on node labels or properties, you can also filter results based on relationships or patterns. This allows you to test if a pattern also has a certain relationship or doesn’t, or if another pattern exists.
The Cypher code below shows how this is done.
There are cases where you might want to retrieve results from patterns, even if they do not match the entire pattern or all of the criteria.
This is how an outer join in SQL functions.
In Cypher, you can use an
OPTIONAL MATCH pattern to try to match it, but if it doesn’t find results, those rows will return
null for those values.
We can see how this would look in Cypher by querying for people whose name starts with a letter and who may work for a company.
Notice that Joe is returned because his name starts with the letter ‘J’, but his company name is null.
That is because he does not have a
WORKS_FOR relationship to a company node.
Since we used optional match, his
Person node is still returned from the first match, but the second match is not found, so returns null.
To see the difference, try running the query without the
We are able to handle many simple graph queries, even at this point, but what happens when we want to extend our patterns past a single relationship? What if we wanted to know who else likes graphs besides Jennifer?
We handle this functionality and many others by simply adding on to our first pattern or matching additional patterns. Let us look at a couple of examples.
Notice that on the second query, we used a comma after the first
MATCH line and added another pattern to match on the next line.
This allows us to chain together patterns, similar to when we used the
WHERE exists(<pattern>) syntax above.
With this structure, though, we can add multiple different patterns and link them together, allowing us to traverse various pieces of the graph with certain patterns.
We have seen how to use the
WHERE clause to filter property values and how to search properties for partial values or string matches.
Patterns helped us maneuver through the graph and check data for specific relationships or paths.
In the next section, we will learn how to use subqueries in Cypher.