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
  • Example 2: Find Person nodes in the graph that have a name of 'Jennifer'. Remember that we can name our variable anything we want, as long as we reference that same name later.

MATCH (jenn:Person {name: 'Jennifer'})
RETURN jenn
  • Example 3: Find which Company Jennifer works for.

Explanation: we know we need to find Jennifer’s Person node, and we need to find the Company node she is connected to. To do that, we need to follow the WORKS_FOR relationship from Jennifer’s Person node to the Company node. We have also specified a label of Company 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 (company) but do not need to give variables for the Person node or WORKS_FOR relationship.

MATCH (:Person {name: 'Jennifer'})-[:WORKS_FOR]->(company:Company)
RETURN company
  • Example 4: Find which Company Jennifer works for, but this time, return only the name of the company.

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

MATCH (:Person {name: 'Jennifer'})-[:WORKS_FOR]->(company:Company)
RETURN company.name

Aliasing Return Values

Not all properties are simple like our company.name 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.

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.

//poorly-named property
MATCH (kristen:Customer {name:'Kristen'})-[rel:PURCHASED]-(order:Order)
RETURN order.orderId, order.orderDate, kristen.customerIdNo, order.orderTotalNoOfItems

//cleaner printed results with aliasing
MATCH (kristen:Customer {name:'Kristen'})-[rel:PURCHASED]-(order:Order)
RETURN order.orderId AS OrderID, order.orderDate AS `Purchase Date`,
       kristen.customerIdNo AS CustomerID, order.orderNumOfLineItems AS `Number Of Items`
Results Without Aliases:

cypher without aliases

Results With Aliases:

cypher with aliases

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

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.

User Contributed Notes