cypher (CQL)是图数据库的必要语言,类似SQL但在一些语法做了改动,代码的编写变得更符合人类直觉

Neo4j文档
Cypher 官方指导学习资源
Cypher 官方文档
Cypher 速查

Cypher是Neo4j的声明性图形查询语言。它由Neo4j工程师于2011年创建,是一种用于图形数据库的SQL等效语言。与SQL类似,Cypher让用户专注于从图中检索什么,而不是如何检索。因此,Cyphers允许用户通过高效且富有表现力的查询来显示以前未知的数据连接和集群,从而使用户能够充分发挥其属性图数据库的潜力。

Cypher提供了一种视觉方式来匹配模式和关系。它依赖于以下ascii艺术类型的语法:(nodes)-[:CONNECT_TO]→(其他节点)。圆括号用于圆形节点,并且-[:ARROWS]→ 关系。编写查询实际上就像通过图形中的数据绘制模式一样。换句话说,诸如节点及其关系之类的实体可视地构建在查询中。这使得Cypher成为一种高度直观的读写语言。

基本概念

Core concepts - Cypher Manual (neo4j.com)

节点 Node

Neo4j图形数据库中的数据实体称为节点。节点在Cypher中使用括号()表示。

MATCH (n:Person {name:'Anna'})
RETURN n.born AS birthYear
  1. MATCH (n:Person {name:'Anna'}): 这是查询的开始。它以 MATCH 子句开头,用于在图数据库中查找并匹配模式。在这个例子中,它正在寻找一个label为 “Person” 的节点,该节点具有属性 “name” 设置为 ‘Anna’。查询的结果将赋值给变量 n
  2. RETURN n.born AS birthYear: 这是 RETURN 子句,用于指定查询的结果应返回哪些数据。它告诉查询返回节点 n 的 ‘born’ 属性的值,并将其重命名为 “birthYear”。

因此,这个查询正在查找一个标记为 “Person”、名为 ‘Anna’ 的节点,然后返回该节点的 ‘born’ 属性的值,并将其重命名为 “birthYear”。如果图数据库包含这样的节点,并且它具有 ‘born’ 属性,那么查询将返回该属性的值。

(在提供的查询中,RETURN n.born AS birthYear 仅是将节点 n 的 ‘born’ 属性的值返回,并且重命名为 “birthYear”,但它并不会修改节点本身的属性。)

一个节点可能的组成:

  • 标签(Label),用于查询数据库中的特定节点。一个节点可能有多个标签。语句中的Person

  • 属性(property),属性在大括号{}中定义,用于向节点提供特定信息,这些信息也可以查询,并进一步提高精确定位数据的能力。语句中的{name:‘Anna’}

  • 变量(variable),变量允许在后面的子句中引用指定的节点。语句中的n

关系 Relationship

图中的节点可以用关系相连接。一个关系必须有一个开始节点、一个结束节点,并且只有一种类型。关系在Cypher中用箭头(例如–>)表示,表示关系的方向(如果使用–,没有>或<,则意味着会只匹配双向关系)。

MATCH (:Person {name: 'Anna'})-[r:KNOWS WHERE r.since < 2020]->(friend:Person)
RETURN count(r) As numberOfFriends
  1. MATCH (:Person {name: 'Anna'})-[r:KNOWS WHERE r.since < 2020]->(friend:Person): 这是查询的起始部分。它以 MATCH 子句开始,首先匹配一个标签为 “Person”、名字为 ‘Anna’ 的节点,(:Person {name: 'Anna'})
  2. 接着,使用连接关系 -[r:KNOWS WHERE r.since < 2020]-> 来匹配一个从 ‘Anna’ 节点出发的 “KNOWS” 关系,这个关系有一个名为 “since” 的属性,其值小于 2020,并且匹配了标签为Person的节点。这个关系被记为变量r,这些节点被记为变量friend。
  3. RETURN count(r) As numberOfFriends: 这是 RETURN 子句,它返回一个名为 “numberOfFriends” 的结果,这个结果的值是 “r” 变量匹配的关系的数量

这个查询在图数据库中查找了与名字为 ‘Anna’ 的人有 “KNOWS” 关系且关系属性 “since” 值小于 2020 的朋友,并返回了这些关系的数量,将其命名为 “numberOfFriends”。

路径 Path

图中的路径由连接的节点和关系组成。探索这些路径是Cypher的核心。

MATCH (n:Person {name: 'Anna'})-[:KNOWS]-{1,5}(friend:Person WHERE n.born < friend.born)
RETURN DISTINCT friend.name AS olderConnections
  1. MATCH (n:Person {name: 'Anna'})-[:KNOWS]-{1,5}(friend:Person WHERE n.born < friend.born): 这是查询的起始部分。它以 MATCH 子句开始,首先匹配一个标签为 “Person”、名字为 ‘Anna’ 的节点,这个节点将被赋予变量 n。接着,通过 [:KNOWS] 匹配 “KNOWS” 关系连接到节点,这个节点将被赋予变量 friend
  2. {1,5}:这是一个范围约束,表示匹配的路径长度应介于1到5跳之间。
  3. (friend:Person WHERE n.born < friend.born): 这部分的目的是过滤出 ‘Anna’ 认识的朋友中出生日期比 ‘Anna’ 更晚的人。这是通过 n.born < friend.born 的条件来实现的,它只会选择出生日期晚于 ‘Anna’ 的朋友。
  4. RETURN DISTINCT friend.name AS olderConnections: 这是 RETURN 子句,它告诉查询返回满足之前匹配条件的朋友节点的名字,并将结果重命名为 “olderConnections”。关键字 DISTINCT 确保结果中不会有重复的名字。

因此,这个查询的目的是找出与名字为 ‘Anna’ 的人通过 “KNOWS” 关系相连的、出生日期比 ‘Anna’ 晚的朋友,然后返回这些朋友的名字,确保结果中没有重复的名字。

MATCH p=shortestPath((:Person {name: 'Anna'})-[:KNOWS*1..10]-(:Person {nationality: 'Canadian'}))
RETURN p

路径也可以指定变量。例如,上面的查询绑定了一个完整的路径模式,该模式匹配从Anna到图中另一个Person节点的最短路径,最短路径距离为10跳,国籍属性设置为Canadian。在这种情况下,RETURN子句返回两个节点之间的完整路径。

子句 Clause

Clauses - Cypher Manual (neo4j.com)

如 MATCH RETURN CREATE DELETE等关键字

查询 Query

Basic queries - Cypher Manual (neo4j.com)

基础使用:MATCH+RETURN

MATCH (keanu:Person {name:'Keanu Reeves'})
RETURN keanu.name AS name, keanu.born AS born

添加过滤条件:

MATCH (bornInEighties:Person)
WHERE bornInEighties.born >= 1980 AND bornInEighties.born < 1990
RETURN bornInEighties.name as name, bornInEighties.born as born
ORDER BY born DESC

查询连接的节点

MATCH (m:Movie {title: 'The Matrix'})<-[d:DIRECTED]-(p:Person)
RETURN p.name as director

查询关系类型:

MATCH (tom:Person {name:'Tom Hanks'})-[r]->(m:Movie)
RETURN type(r) AS type, m.title AS movie

在子句中添加关系表达式

MATCH (:Person {name:'Tom Hanks'})-[r:!ACTED_IN]->(m:Movie)
Return type(r) AS type, m.title AS movies

查找路径:

MATCH (tom:Person {name:'Tom Hanks'})--{2}(colleagues:Person)
RETURN DISTINCT colleagues.name AS name, colleagues.born AS bornIn
ORDER BY bornIn
LIMIT 5
查找距离目标节点正好2跳的节点

MATCH (p:Person {name:'Tom Hanks'})--{1,4}(colleagues:Person)
RETURN DISTINCT colleagues.name AS name, colleagues.born AS bornIn
ORDER BY bornIn, name
LIMIT 5
查找距离目标节点1-4跳的节点

查找最短路径

MATCH p=shortestPath(
(:Person {name:"Keanu Reeves"})-[*]-(:Person {name:"Tom Hanks"})
)
RETURN p