Cypher 样式指南
Cypher® 样式指南的目的是使查询尽可能易读。
有关标签、关系类型和属性的命名规则和建议,请参阅命名规则和建议。
确保您的查询遵循样式规则的最佳方法是使用 cypherfmt
,即官方的 Cypher 格式化工具。它作为 Neo4j VS Code 扩展的一部分提供,也可以通过 Neo4j Cypher Language Support npm 包作为命令行工具使用。
一般建议
-
在散文中引用 Cypher 语言结构时,请使用
等宽
字体并遵循样式规则。 -
引用标签和关系类型时,冒号应包含在内,例如:
:Label
,:REL_TYPE
。 -
引用函数时,请使用小驼峰命名法和括号。例如:
toString()
。 -
如果您将 Cypher 语句存储在单独的文件中,请使用文件扩展名
.cypher
。
缩进和换行
-
新子句另起一行。
MATCH (n) WHERE n.name CONTAINS 's' RETURN n.name
MATCH (n)
WHERE n.name CONTAINS 's'
RETURN n.name
-
ON CREATE
和ON MATCH
缩进两个空格。如果两者都存在,ON CREATE
应放在ON MATCH
之前。
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
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
-
子查询在开括号后另起一行,并(额外)缩进两个空格。闭括号单独占一行。
MATCH (a:A)
WHERE
EXISTS { MATCH (a)-->(b:B) WHERE b.prop = 'yellow' }
RETURN a.foo
MATCH (a:A)
WHERE EXISTS
{MATCH (a)-->(b:B)
WHERE b.prop = 'yellow'}
RETURN a.foo
MATCH (a:A)
WHERE EXISTS {
MATCH (a)-->(b:B)
WHERE b.prop = 'yellow'
}
RETURN a.foo
-
如果使用简化子查询形式,请勿换行。
MATCH (a:A)
WHERE EXISTS {
(a)-->(b:B)
}
RETURN a.prop
MATCH (a:A)
WHERE EXISTS { (a)-->(b:B) }
RETURN a.prop
-
尽可能将行长限制在 80 个字符。换行应从最外层组开始应用,每个嵌套组都进行换行,直到行适合或无法再插入更多换行为止。每个嵌套的换行组增加两个空格的缩进。
MATCH (n)
WHERE n.prop <> 'a' AND n.prop <> 'b' AND n.prop <> 'c' AND n.prop <> 'd' AND n.prop <> 'e'
RETURN n
MATCH (n)
WHERE
n.prop <> 'a' AND
n.prop <> 'b' AND
n.prop <> 'c' AND
n.prop <> 'd' AND
n.prop <> 'e'
RETURN n
-
ORDER BY
和LIMIT
子句另起一行。
MATCH (n)
RETURN 5 ORDER BY n.prop LIMIT 10
MATCH (n)
RETURN 5
ORDER BY n.prop
LIMIT 10
-
包含
CASE
表达式的组应始终换行,并且每个WHEN
、ELSE
和END
都应另起一行。此外,WHEN
和ELSE
应增加两个空格的缩进。
MATCH (n:Person {name: 'Alice'})
RETURN CASE WHEN n.age >= 18 THEN 'Adult' ELSE 'Minor' END AS ageGroup
MATCH (n:Person {name: 'Alice'})
RETURN
CASE
WHEN n.age >= 18 THEN 'Adult'
ELSE 'Minor'
END AS ageGroup
-
当一行以列表或映射字面量结尾,且该字面量不符合最大行宽时,将开括号或大括号放在引入它的子句的同一行。字面量的每个元素另起一行,缩进比包含开括号或大括号的行多两个空格。在原始缩进级别关闭字面量。
RETURN
[
"Alice",
"Bob",
"Charlie",
"David",
"Eve",
"Frank",
"Grace",
"Heidi",
"Ivan",
"Judy"
]
RETURN [
"Alice",
"Bob",
"Charlie",
"David",
"Eve",
"Frank",
"Grace",
"Heidi",
"Ivan",
"Judy"
]
-
可以使用一个空行来分隔子句、查询或注释。
MATCH (n)-[r]->(m)
RETURN n, r, m
MATCH (n)-[r]->(m)
RETURN n, r, m
大小写
-
关键词使用大写。
match (p:Person)
where p.name starts with 'Ma'
return p.name
MATCH (p:Person)
WHERE p.name STARTS WITH 'Ma'
RETURN p.name
-
值
null
使用小写。
WITH NULL AS n1, Null AS n2
RETURN n1 IS NULL AND n2 IS NOT NULL
WITH null AS n1, null AS n2
RETURN n1 IS NULL AND n2 IS NOT NULL
-
BOOLEAN
字面量(true
和false
)使用小写。
WITH TRUE AS b1, False AS b2
RETURN b1 AND b2
WITH true AS b1, false AS b2
RETURN b1 AND b2
-
以下情况使用小写开头的驼峰命名法:
-
函数
-
属性
-
变量
-
参数
-
CREATE (N:Label {Prop: 0})
WITH N, RAND() AS Rand, $pArAm AS MAP
RETURN Rand, MAP.property_key, count(N)
CREATE (n:Label {prop: 0})
WITH n, rand() AS rand, $param AS map
RETURN rand, map.propertyKey, count(n)
间距
-
对于字面量映射
-
开大括号与第一个键之间无空格
-
键与冒号之间无空格
-
冒号与值之间有一个空格
-
值与逗号之间无空格
-
逗号与下一个键之间有一个空格
-
最后一个值与闭大括号之间无空格
-
WITH { key1 :'value' ,key2 : 42 } AS map
RETURN map
WITH {key1: 'value', key2: 42} AS map
RETURN map
-
模式中标签/类型谓词与属性谓词之间有一个空格。
MATCH (p:Person{property: -1})-[:KNOWS {since: 2016}]->()
RETURN p.name
MATCH (p:Person {property: -1})-[:KNOWS {since: 2016}]->()
RETURN p.name
-
模式中无空格。
MATCH (:Person) --> (:Vehicle)
RETURN count(*)
MATCH (:Person)-->(:Vehicle)
RETURN count(*)
-
运算符周围使用换行符后的空格。
MATCH p=(s)-->(e)
WHERE s.name<>e.name
RETURN length(p)
MATCH p = (s)-->(e)
WHERE s.name <> e.name
RETURN length(p)
-
标签谓词中无空格。
MATCH (person : Person : Owner )
RETURN person.name
MATCH (person:Person:Owner)
RETURN person.name
-
列表和枚举中每个逗号后使用一个空格。
MATCH (),()
WITH ['a','b',3.14] AS list
RETURN list,2,3,4
MATCH (), ()
WITH ['a', 'b', 3.14] AS list
RETURN list, 2, 3, 4
-
函数调用括号内无填充空格。
RETURN split( 'original', 'i' )
RETURN split('original', 'i')
-
简单子查询表达式内使用填充空格。
MATCH (a:A)
WHERE EXISTS {(a)-->(b:B)}
RETURN a.prop
MATCH (a:A)
WHERE EXISTS { (a)-->(b:B) }
RETURN a.prop
模式
-
当模式换行时,应在箭头后换行,而不是在箭头前。
MATCH (:Person)-->(vehicle:Car)-->(:Company)
<--(:Country)
RETURN count(vehicle)
MATCH (:Person)-->(vehicle:Car)-->(:Company)<--
(:Country)
RETURN count(vehicle)
-
当变量不会被使用时,使用匿名节点和关系。
MATCH (kate:Person {name: 'Kate'})-[r:LIKES]-(c:Car)
RETURN c.type
MATCH (:Person {name: 'Kate'})-[:LIKES]-(c:Car)
RETURN c.type
-
将模式链接在一起以避免重复变量。
MATCH (:Person)-->(vehicle:Car), (vehicle:Car)-->(:Company)
RETURN count(vehicle)
MATCH (:Person)-->(vehicle:Car)-->(:Company)
RETURN count(vehicle)
-
将命名节点放在匿名节点之前。
MATCH ()-->(vehicle:Car)-->(manufacturer:Company)
WHERE manufacturer.foundedYear < 2000
RETURN vehicle.mileage
MATCH (manufacturer:Company)<--(vehicle:Car)<--()
WHERE manufacturer.foundedYear < 2000
RETURN vehicle.mileage
-
将锚点节点保持在
MATCH
子句的开头。
MATCH (:Person)-->(vehicle:Car)-->(manufacturer:Company)
WHERE manufacturer.foundedYear < 2000
RETURN vehicle.mileage
MATCH (manufacturer:Company)<--(vehicle:Car)<--(:Person)
WHERE manufacturer.foundedYear < 2000
RETURN vehicle.mileage
-
优先使用传出(从左到右)模式关系,而非传入模式关系。
MATCH (:Country)-->(:Company)<--(vehicle:Car)<--(:Person)
RETURN vehicle.mileage
MATCH (:Person)-->(vehicle:Car)-->(:Company)<--(:Country)
RETURN vehicle.mileage
元字符
-
对于字面量
STRING
值,使用单引号'
。
RETURN "Cypher"
RETURN 'Cypher'
-
对于包含单引号字符的字面量
STRING
值,请忽略此规则。如果STRING
同时包含单引号和双引号,请使用产生最少转义的格式。如果两者相同,优先使用单引号。
RETURN 'Cypher\'s a nice language', "Mats' quote: \"statement\""
RETURN "Cypher's a nice language", 'Mats\' quote: "statement"'
-
避免使用需要用反引号引用的字符和关键词。
MATCH (`odd-ch@racter$`:`Spaced Label` {`&property`: 42})
RETURN labels(`odd-ch@racter$`)
MATCH (node:NonSpacedLabel {property: 42})
RETURN labels(node)
-
语句末尾不要使用分号。
RETURN 1;
RETURN 1