DEV Community

Cover image for The Cypher Query Language - Best Practices
Memgraph for Memgraph

Posted on

The Cypher Query Language - Best Practices

Cypher has a defined set of rules for writing readable and well-designed constructs like any other programming or query language. By following this guide, you will learn how to format and organize Cypher queries so that naming conventions and formatting are consistent and understandable to everyone.

Don't worry if you are still new to graph databases or Cypher. Most example queries are easy to understand from context and don't require any advanced knowledge.

Data model styling

Defining your data model is one of the most important steps when it comes to styling. Because you will use these constructs throughout your project, it would be wise to think about the naming convention and formatting rules before committing to specific ones.
Sticking to shared best practices is by far the best choice because it enables other users to easily read and understand your data model and queries. In this section, you'll find recommendations on naming nodes and relationships, their properties, variables... and so on.

Nodes

When it comes to nodes, the most important factor is styling labels. Node labels should be defined in CamelCase, which means that the first letter of each word begins with a capital letter. Because Cypher is case-sensitive, it is important to uphold this style throughout every query you write.

(:Country)
(:City)
(:CapitalCity)
Enter fullscreen mode Exit fullscreen mode

Relationships

Relationship types are styled upper-case and use the underscore character _ to separate multiple words.

[:LIVES_IN]
(:BORDERS_WITH)
Enter fullscreen mode Exit fullscreen mode

Properties, variables, parameters, aliases, and functions

Property keys, variables, parameters, aliases, and functions should have a camelCase style where the first letter of the word is lower-case, and the first letter of each following word is a capital letter. All of these constructs are case-sensitive, so capitalization must match either what is in the database (properties), what is already defined in the query (variables, parameters, aliases), or Cypher definitions (functions).

dateOfBirth // Property key
largestCountry // Variable
size() // Function
countryOne // Alias
Enter fullscreen mode Exit fullscreen mode

Clauses

Clauses should be defined with capital letters, even if they consist of two or more words. Each new clause should be placed at the beginning of a new line to ensure complete readability. While clauses are not case sensitive, we strongly discourage you from using any other style to avoid confusion.

MATCH (c:Country)
WHERE c.name = 'UK'
RETURN c;

WITH "2021-01-01" as currentDate
MATCH (p:Person)
WHERE p.birthdate > currentDate
RETURN p.name;
Enter fullscreen mode Exit fullscreen mode

Keywords

Aside from clauses, several keywords should be in the upper case even though they are not case sensitive. These include DISTINCT, IN, STARTS WITH, CONTAINS, NOT, AND, OR and AS.

MATCH (c:Country)
WHERE c.name CONTAINS 'United' AND c.population > 9000000
RETURN c AS Country;
Enter fullscreen mode Exit fullscreen mode

Indentations and line breaks

Sometimes it's helpful to separate new clauses with an indent. Even though they are in a new line, subqueries should be indented to ensure readability.
If there are multiple subqueries, they can be further grouped by using curly brackets.

//Indent 2 spaces on lines with ON CREATE or ON MATCH subqueries
MATCH (p:Person {name: 'Helga'})
MERGE (c:Country {name: 'UK'})
MERGE (p)-[l:LIVES_IN]->(c)
  ON CREATE SET l.movedIn = date({year: 2020})
  ON MATCH SET l.modified = date()
RETURN p, l, c;

//Indent 2 spaces with braces for subqueries
MATCH (p:Person)
WHERE EXISTS {
  MATCH (p)-->(c:Country)
  WHERE c.name = 'UK'
}
RETURN p;
Enter fullscreen mode Exit fullscreen mode

An exception to this rule would be a one-line subquery where you don't need to use a new line or an indent.

MATCH (p:Person)
WHERE EXISTS { MATCH (p)-->(c:Country {name: 'UK'}) }
RETURN p;
Enter fullscreen mode Exit fullscreen mode

Metacharacters

Quotes

When it comes to quotes, a simple rule is to use whichever provides the fewest escaped characters in the string. If escaped characters are not needed, or their number is the same for single and double quotes, you should favor single quotes.

// Bad syntax
RETURN 'Memgraph\'s mission is: ', "A very famous quote is: \"Astra inclinant, sed non obligant.\"";

// Recommended syntax
RETURN "Memgraph's mission is: ", 'A very famous quote is: "Astra inclinant, sed non obligant."';
Enter fullscreen mode Exit fullscreen mode

Semicolons

In most cases, a semicolon at the end of a Cypher query is unnecessary. Nevertheless, we recommend that you put a semicolon at the end of a Cypher query. The exception is when you have a script or a block with multiple separate Cypher queries that should be executed independently.

MATCH (c:Country {name: 'UK'})
RETURN c;

MATCH (c:Country {name: 'Germany'})
RETURN c;
Enter fullscreen mode Exit fullscreen mode

Null and Boolean Values

Boolean literals and null values should always be lower case.

// Bad syntax
MATCH (c:Country)
WHERE c.island = NULL
  SET islandCountry = True
RETURN c;

// Recommended syntax
MATCH (c:Country)
WHERE c.island = null
  SET islandCountry = true
RETURN c;
Enter fullscreen mode Exit fullscreen mode

Pattern styling

  • When you have a pattern that is too long for one line, the recommended practice is to break after an arrow, not before it.
// Bad syntax
MATCH (:Country)-->(:Person)-->(:Person)
      <--(c:Country)
RETURN c.name;

// Recommended syntax
MATCH (:Country)-->(:Person)-->(:Person)<--
      (c:Country)
RETURN c.name;
Enter fullscreen mode Exit fullscreen mode
  • If you don't plan on using a variable in the query, it's better to use anonymous nodes and relationships instead.
// Bad syntax
MATCH (c:Country {name: 'UK'})<-[l:LIVES_IN]-(p:Person)
RETURN p.name;

// Recommended syntax
MATCH (:Country {name: 'UK'})<-[:LIVES_IN]-(p:Person)
RETURN p.name;
Enter fullscreen mode Exit fullscreen mode
  • Nodes with assigned variables should come before anonymous nodes and relationships if possible. The same goes for nodes that are starting points or the central focus of the query.
// Bad syntax
MATCH (:Person)-[:LIVES_IN]->(c:Country {name: 'UK'})
RETURN c;

// Recommended syntax
MATCH (c:Country {name: 'UK'})<-[:LIVES_IN]-(:Person)
RETURN c;
Enter fullscreen mode Exit fullscreen mode
  • Patterns should be ordered so that left-to-right relationships (arrows) come at the beginning of the query.
// Bad syntax
MATCH (c:Country)<-[:BORDERS_WITH]-(:Country)<-[:LIVES_IN]-(:Person)
RETURN c;

// Recommended syntax
MATCH (:Person)-[:LIVES_IN]->(:Country)-[:BORDERS_WITH]->(c:Country)
RETURN c;
Enter fullscreen mode Exit fullscreen mode

Spacing

Spacing has a significant impact on the readability of queries. Some of the recommended practices when it comes to spacing are:

  • There should be one space between property predicates and label/type predicates.
// Bad syntax
MATCH (:Country   {name: 'UK'})<-[:LIVES_IN{since: 2010}]-(p:Person)
RETURN p.name;

// Recommended syntax
MATCH (:Country {name: 'UK'})<-[:LIVES_IN {since: 2010}]-(p:Person)
RETURN p.name;
Enter fullscreen mode Exit fullscreen mode
  • There should be no spaces in label predicates.
// Bad syntax
MATCH (c: Country:  City)
RETURN c.name;

// Recommended syntax
MATCH (c:Country:City)
RETURN c.name;
Enter fullscreen mode Exit fullscreen mode
  • There should be no spaces in patterns.
// Bad syntax
MATCH (c:Country) --> (:City) 
RETURN c.name;

// Recommended syntax
MATCH (c:Country)-->(:City) 
RETURN c.name;
Enter fullscreen mode Exit fullscreen mode
  • There should be one space on both sides of an operator.
// Bad syntax
MATCH (c:Country)
WHERE population>100000
RETURN c.name;

// Recommended syntax
MATCH (c:Country)
WHERE population > 100000
RETURN c.name;
Enter fullscreen mode Exit fullscreen mode
  • There should be one space between elements in a list (after each comma).
// Bad syntax
WITH ['UK','US','Germany'] as list
MATCH (c:Country)
WHERE c.name IN list
RETURN c.name;

// Recommended syntax
WITH ['UK', 'US', 'Germany'] as list
MATCH (c:Country)
WHERE c.name IN list
RETURN c.name;
Enter fullscreen mode Exit fullscreen mode
  • Function call parentheses should only have one space after each comma.
// Bad syntax
RETURN split( 'A', 'B' , 'C' );

// Recommended syntax
RETURN split('A', 'B', 'C');
Enter fullscreen mode Exit fullscreen mode
  • Map literals should only have one space after each comma and one space separating a colon and a value.
// Bad syntax
WITH { name :'UK' ,population  :  70000000 } AS country
RETURN country;

// Recommended syntax
WITH {name: 'UK', population: 70000000} AS country
RETURN country;
Enter fullscreen mode Exit fullscreen mode

Conclusion

Having a well-defined style for writing queries is a technical must-have. It makes it easier and faster to understand queries that other people have written while also enabling everyone to contribute in a meaningful way without having to worry about the format. Whenever you are not sure about a naming convention or the structure of your query, take a quick look at this guide.

If you are new to Cypher, we suggest taking our ten-day Cypher email course. If you already use Cypher, please look at our Cypher manual and Complete Cypher Cheat Sheet. If you have any questions if you have any questions, join our growing Community on Discord.

Read more about cypher on memgraph.com

Top comments (0)