Cypher查询语言 - 最佳实践
#database #memgraph #cypher #graphdatabase

cypher 具有一组定义的规则,用于编写可读且精心设计的构造,例如任何其他编程或查询语言。通过遵循本指南,您将学习如何格式化和组织Cypher查询,以便每个人的命名惯例和格式都一致且可以理解。

不用担心您是否仍然是图形数据库或Cypher的新手。大多数示例查询易于从上下文中理解,不需要任何高级知识。

数据模型样式

定义数据模型是造型方面最重要的步骤之一。因为您将在整个项目中使用这些结构,所以在承诺特定规则之前考虑命名约定和格式化是明智的。
坚持共享的最佳实践是迄今为止最佳选择,因为它使其他用户可以轻松阅读和理解您的数据模型和查询。在本节中,您将找到有关命名节点和关系,其属性,变量...等等的建议。

节点

关于节点,最重要的因素是样式标签。节点标签应在骆驼壳中定义,这意味着每个单词的首字母以大写字母开头。因为 cypher对案例敏感,因此在您编写的每个查询中都要维护这种样式很重要。

(:Country)
(:City)
(:CapitalCity)

关系

关系类型是样式的上案例,并使用下划线字符_分开多个单词。

[:LIVES_IN]
(:BORDERS_WITH)

属性,变量,参数,别名和功能

属性键,变量,参数,别名和函数应具有骆驼壳样式,其中单词的第一个字母是较低的,每个单词的第一个字母是大写字母。所有这些构造都是对病例敏感的,因此资本化必须与数据库(属性)中的内容相匹配,查询(变量,参数,别名)或Cypher定义(functions)中已经定义的内容。

dateOfBirth // Property key
largestCountry // Variable
size() // Function
countryOne // Alias

条款

条款应用大写字母定义,即使它们由两个或更多单词组成。每个新条款都应放置在新行的开头,以确保完整的可读性。虽然条款不敏感,但我们强烈阻止您使用任何其他样式避免混乱。

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;

关键字

除了条款外,即使不敏感的情况,也应在上层情况下有几个关键字。其中包括DISTINCTINSTARTS WITHCONTAINSNOTANDORAS

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

凹痕和线路断裂

有时用缩进分离新条款很有帮助。即使他们处于新系列,也应缩进子征服以确保可读性。
如果有多个子查询,可以使用卷曲括号进一步分组。

//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;

此规则的一个例外将是一个单行子查询,您不需要使用新行或缩进。

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

metacharacers

引号

在引号时,一个简单的规则是使用该字符串中最少的逃逸字符。如果不需要逃脱的字符,或者单品和双引号的数字相同,则应偏爱单句话。

// 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."';

分号

在大多数情况下,无需在密码查询结束时进行半分离。不过,我们建议您在密码查询结束时放置一个分号。例外是当您有一个脚本或一个具有多个独立的Cypher查询的块时,应独立执行。

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

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

零和布尔值

布尔文字和null值应始终是较低的情况。

// 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;

图案样式

  • 当您的图案对于一行而言太长时,建议的做法是在箭头之后折断,而不是在它之前。
// Bad syntax
MATCH (:Country)-->(:Person)-->(:Person)
      <--(c:Country)
RETURN c.name;

// Recommended syntax
MATCH (:Country)-->(:Person)-->(:Person)<--
      (c:Country)
RETURN c.name;
  • 如果您不打算在查询中使用变量,则最好使用匿名节点和关系。
// 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;
  • 带有分配变量的节点应在匿名节点和关系之前出现。对于起点或查询的主要焦点的节点也是如此。
// Bad syntax
MATCH (:Person)-[:LIVES_IN]->(c:Country {name: 'UK'})
RETURN c;

// Recommended syntax
MATCH (c:Country {name: 'UK'})<-[:LIVES_IN]-(:Person)
RETURN c;
  • 应订购模式,以便从左右的关系(箭头)出现在查询的开头。
// 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;

间距

间距对查询的可读性有重大影响。间距方面的一些推荐做法是:

  • 属性谓词和标签/类型谓词之间应该有一个空间。
// 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;
  • 标签谓词中不应没有空间。
// Bad syntax
MATCH (c: Country:  City)
RETURN c.name;

// Recommended syntax
MATCH (c:Country:City)
RETURN c.name;
  • 图案中不应有空格。
// Bad syntax
MATCH (c:Country) --> (:City) 
RETURN c.name;

// Recommended syntax
MATCH (c:Country)-->(:City) 
RETURN c.name;
  • 操作员的两侧应该有一个空间。
// Bad syntax
MATCH (c:Country)
WHERE population>100000
RETURN c.name;

// Recommended syntax
MATCH (c:Country)
WHERE population > 100000
RETURN c.name;
  • 列表中的元素之间应该有一个空间(每个逗号之后)。
// 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;
  • 函数呼叫括号应在每个逗号后只有一个空间。
// Bad syntax
RETURN split( 'A', 'B' , 'C' );

// Recommended syntax
RETURN split('A', 'B', 'C');
  • MAP文字在每个逗号后只有一个空间,一个空间将结肠和值分开。
// Bad syntax
WITH { name :'UK' ,population  :  70000000 } AS country
RETURN country;

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

结论

具有编写疑问的定义明确的样式是技术必不可少的。理解其他人所写的查询,同时也使每个人都能以有意义的方式做出贡献,而不必担心格式,这使得变得更加容易,更快。只要您不确定命名约定或查询的结构,请快速查看本指南。

如果您是Cypher的新手,我们建议您服用我们为期十天的Cypher email course。如果您已经使用了Cypher,请查看我们的Cypher manualComplete Cypher Cheat Sheet。如果您有任何疑问,请加入我们不断增长的Community on Discord

Read more about cypher on memgraph.com