Cypher styleguide

This appendix contains the recommended style when writing Cypher queries.

This appendix contains the following:

The purpose of the styleguide is to make the code as easy to read as possible, and thereby contributing to lower cost of maintenance.

For rules and recommendations for naming of labels, relationship types and properties, please see the Naming rules and recommendations.

1. General recommendations

  • When using Cypher language constructs in prose, use a monospaced font and follow the styling rules.

  • When referring to labels and relationship types, the colon should be included as follows: :Label, :REL_TYPE.

  • When referring to functions, use lower camel case and parentheses should be used as follows: shortestPath(). Arguments should normally not be included.

  • If you are storing Cypher statements in a separate file, use the file extension .cypher.

2. Indentation and line breaks

  • Start a new clause on a new line.

    Bad
    MATCH (n) WHERE n.name CONTAINS 's' RETURN n.name
    Good
    MATCH (n)
    WHERE n.name CONTAINS 's'
    RETURN n.name
  • Indent ON CREATE and ON MATCH with two spaces. Put ON CREATE before ON MATCH if both are present.

    Bad
    MERGE (n) ON CREATE SET n.prop = 0
    MERGE (a:A)-[:T]-(b:B)
    ON MATCH SET b.name = 'you'
    ON CREATE SET a.name = 'me'
    RETURN a.prop
    Good
    MERGE (n)
      ON CREATE SET n.prop = 0
    MERGE (a:A)-[:T]-(b:B)
      ON CREATE SET a.name = 'me'
      ON MATCH SET b.name = 'you'
    RETURN a.prop
  • Start a subquery on a new line after the opening brace, indented with two (additional) spaces. Leave the closing brace on its own line.

    Bad
    MATCH (a:A)
    WHERE
      EXISTS { MATCH (a)-->(b:B) WHERE b.prop = $param }
    RETURN a.foo
    Also bad
    MATCH (a:A)
    WHERE EXISTS
    {MATCH (a)-->(b:B)
    WHERE b.prop = $param}
    RETURN a.foo
    Good
    MATCH (a:A)
    WHERE EXISTS {
      MATCH (a)-->(b:B)
      WHERE b.prop = $param
    }
    RETURN a.foo
  • Do not break the line if the simplified subquery form is used.

    Bad
    MATCH (a:A)
    WHERE EXISTS {
      (a)-->(b:B)
    }
    RETURN a.prop
    Good
    MATCH (a:A)
    WHERE EXISTS { (a)-->(b:B) }
    RETURN a.prop

3. Casing

  • Write keywords in upper case.

    Bad
    match (p:Person)
    where p.name starts with 'Ma'
    return p.name
    Good
    MATCH (p:Person)
    WHERE p.name STARTS WITH 'Ma'
    RETURN p.name
  • Write the value null in lower case.

    Bad
    WITH NULL AS n1, Null AS n2
    RETURN n1 IS NULL AND n2 IS NOT NULL
    Good
    WITH null AS n1, null as n2
    RETURN n1 IS NULL AND n2 IS NOT NULL
  • Write boolean literals (true and false) in lower case.

    Bad
    WITH TRUE AS b1, False AS b2
    RETURN b1 AND b2
    Good
    WITH true AS b1, false AS b2
    RETURN b1 AND b2
  • Use camel case, starting with a lower-case character, for:

    • functions

    • properties

    • variables

    • parameters

      Bad
      CREATE (N {Prop: 0})
      WITH RAND() AS Rand, $pArAm AS MAP
      RETURN Rand, MAP.property_key, Count(N)
      Good
      CREATE (n {prop: 0})
      WITH rand() AS rand, $param AS map
      RETURN rand, map.propertyKey, count(n)

4. Spacing

  • For literal maps:

    • No space between the opening brace and the first key

    • No space between key and colon

    • One space between colon and value

    • No space between value and comma

    • One space between comma and next key

    • No space between the last value and the closing brace

      Bad
      WITH { key1 :'value' ,key2  :  42 } AS map
      RETURN map
      Good
      WITH {key1: 'value', key2: 42} AS map
      RETURN map
  • One space between label/type predicates and property predicates in patterns.

    Bad
    MATCH (p:Person{property: -1})-[:KNOWS   {since: 2016}]->()
    RETURN p.name
    Good
    MATCH (p:Person {property: -1})-[:KNOWS {since: 2016}]->()
    RETURN p.name
  • No space in patterns.

    Bad
    MATCH (:Person) --> (:Vehicle)
    RETURN count(*)
    Good
    MATCH (:Person)-->(:Vehicle)
    RETURN count(*)
  • Use a wrapping space around operators.

    Bad
    MATCH p=(s)-->(e)
    WHERE s.name<>e.name
    RETURN length(p)
    Good
    MATCH p = (s)-->(e)
    WHERE s.name <> e.name
    RETURN length(p)
  • No space in label predicates.

    Bad
    MATCH (person    : Person  :  Owner  )
    RETURN person.name
    Good
    MATCH (person:Person:Owner)
    RETURN person.name
  • Use a space after each comma in lists and enumerations.

    Bad
    MATCH (),()
    WITH ['a','b',3.14] AS list
    RETURN list,2,3,4
    Good
    MATCH (), ()
    WITH ['a', 'b', 3.14] AS list
    RETURN list, 2, 3, 4
  • No padding space within function call parentheses.

    Bad
    RETURN split( 'original', 'i' )
    Good
    RETURN split('original', 'i')
  • Use padding space within simple subquery expressions.

    Bad
    MATCH (a:A)
    WHERE EXISTS {(a)-->(b:B)}
    RETURN a.prop
    Good
    MATCH (a:A)
    WHERE EXISTS { (a)-->(b:B) }
    RETURN a.prop

5. Patterns

  • When patterns wrap lines, break after arrows, not before.

    Bad
    MATCH (:Person)-->(vehicle:Car)-->(:Company)
          <--(:Country)
    RETURN count(vehicle)
    Good
    MATCH (:Person)-->(vehicle:Car)-->(:Company)<--
          (:Country)
    RETURN count(vehicle)
  • Use anonymous nodes and relationships when the variable would not be used.

    Bad
    CREATE (a:End {prop: 42}),
           (b:End {prop: 3}),
           (c:Begin {prop: id(a)})
    Good
    CREATE (a:End {prop: 42}),
           (:End {prop: 3}),
           (:Begin {prop: id(a)})
  • Chain patterns together to avoid repeating variables.

    Bad
    MATCH (:Person)-->(vehicle:Car), (vehicle:Car)-->(:Company)
    RETURN count(vehicle)
    Good
    MATCH (:Person)-->(vehicle:Car)-->(:Company)
    RETURN count(vehicle)
  • Put named nodes before anonymous nodes.

    Bad
    MATCH ()-->(vehicle:Car)-->(manufacturer:Company)
    WHERE manufacturer.foundedYear < 2000
    RETURN vehicle.mileage
    Good
    MATCH (manufacturer:Company)<--(vehicle:Car)<--()
    WHERE manufacturer.foundedYear < 2000
    RETURN vehicle.mileage
  • Keep anchor nodes at the beginning of the MATCH clause.

    Bad
    MATCH (:Person)-->(vehicle:Car)-->(manufacturer:Company)
    WHERE manufacturer.foundedYear < 2000
    RETURN vehicle.mileage
    Good
    MATCH (manufacturer:Company)<--(vehicle:Car)<--(:Person)
    WHERE manufacturer.foundedYear < 2000
    RETURN vehicle.mileage
  • Prefer outgoing (left to right) pattern relationships to incoming pattern relationships.

    Bad
    MATCH (:Country)-->(:Company)<--(vehicle:Car)<--(:Person)
    RETURN vehicle.mileage
    Good
    MATCH (:Person)-->(vehicle:Car)-->(:Company)<--(:Country)
    RETURN vehicle.mileage

6. Meta-characters

  • Use single quotes, ', for literal string values.

    Bad
    RETURN "Cypher"
    Good
    RETURN 'Cypher'
    • Disregard this rule for literal strings that contain a single quote character. If the string has both, use the form that creates the fewest escapes. In the case of a tie, prefer single quotes.

      Bad
      RETURN 'Cypher\'s a nice language', "Mats' quote: \"statement\""
      Good
      RETURN "Cypher's a nice language", 'Mats\' quote: "statement"'
  • Avoid having to use back-ticks to escape characters and keywords.

    Bad
    MATCH (`odd-ch@racter$`:`Spaced Label` {`&property`: 42})
    RETURN labels(`odd-ch@racter$`)
    Good
    MATCH (node:NonSpacedLabel {property: 42})
    RETURN labels(node)
  • Do not use a semicolon at the end of the statement.

    Bad
    RETURN 1;
    Good
    RETURN 1