一、节点语法
- Cpyher用一对括号来表示一个节点,节点的属性表示为键值对列表,括在一对大括号内。最简单的形式,
()
代表一个匿名的、无特征的节点。如果我们想在别处引用该节点,我们可以添加一个变量,例如:(matrix)
。变量仅限于单个语句。它在另一个语句中可能具有不同的含义或没有含义。
()
(matrix)
(:Movie)
(matrix:Movie)
(matrix:Movie {title: 'The Matrix'})
(matrix:Movie {title: 'The Matrix', released: 1997})
二、关系语法
- 用一对破折号来表示无向关系,定向关系的一端会有一个箭头
-[role]->
-[:ACTED_IN]->
-[role:ACTED_IN]->
-[role:ACTED_IN {roles: ['Neo']}]->
- 关系的括号对中的语法和语义与节点括号之间使用的语法和语义非常相似。可以给关系定义一个变量以便在语句的其他地方使用。关系的类型(例如,
:ACTED_IN
)类似于节点的标签。属性(例如,roles
)完全等同于节点属性。
三、模式语法
- 一个简单模式
(keanu:Person:Actor {name: 'Keanu Reeves'})-[role:ACTED_IN {roles: ['Neo']}]->(matrix:Movie {title: 'The Matrix'})
四、模式变量
- 为了增加模块化并减少重复,Cypher 允许将模式分配给变量。这允许检查匹配路径,用于其他表达式等。
acted_in = (:Person)-[:ACTED_IN]->(:Movie)
五、实践操作
- 创建数据
CREATE (:Movie {title: 'The Matrix', released: 1997})
还可以返回创建的数据
CREATE (a:Person {name: 'Tom Hanks', born: 1956})-[r:ACTED_IN {roles: ['Forrest']}]->(m:Movie {title: 'Forrest Gump', released: 1994})
return a, r, m
- 匹配模式
# 查找所有标有Movie标签的节点
MATCH (m:Movie)
RETURN m
# 查找一个特定的人
MATCH (p:Person {name: 'Keanu Reeves'})
RETURN p
# 查找一些联系
MATCH (p:Person {name: 'Tom Hanks'})-[r:ACTED_IN]->(m:Movie)
RETURN ,
- 给图进行扩展,先匹配现有的连接点,然后通过关系将新创建的节点附加到它们
MATCH (p:Person {name: 'Tom Hanks'})
CREATE (m:Movie {title: 'Cloud Atlas', released: 2012})
CREATE (p)-[r:ACTED_IN {roles: ['Zachry']}]->(m)
RETURN p, r, m
- 完成模式
Cpyher中MERGE相当于MATCH或CREATE的组合,它在创建数据之前检查数据是否存在。MERGE允许提供要设置的其他属性ON CREATE。
MERGE (m:Movie {title: 'Cloud Atlas'})
ON CREATE SET = 2012
RETURN m
MERGE
也可以断言关系只创建一次。为此,您必须从先前的模式匹配中传入两个节点。
MATCH (m:Movie {title: 'Cloud Atlas'})
MATCH (p:Person {name: 'Tom Hanks'})
MERGE (p)-[r:ACTED_IN]->(m)
ON CREATE SET =['Zachry']
RETURN p, r, m
如果您选择只传入前一个子句中的一个节点,则MERGE
提供了一个有趣的功能。然后它只会在给定模式的提供节点的直接邻域内匹配,如果没有找到,则创建它。这对于创建例如树结构非常方便。
CREATE (y:Year {year: 2014})
MERGE (y)<-[:IN_YEAR]-(m10:Month {month: 10})
MERGE (y)<-[:IN_YEAR]-(m11:Month {month: 11})
RETURN y, m10, m11
- 过滤结果
现在我们将研究过滤结果的选项,只返回我们感兴趣的数据子集。这些过滤条件使用WHERE
子句表示。这个子句允许使用任意数量的布尔表达式和为此谓词,结合AND
,OR
,XOR
和NOT
。最简单的谓词是比较;尤其是平等。
MATCH (m:Movie)
WHERE = 'The Matrix'
RETURN m
相当于
MATCH (m:Movie {title: 'The Matrix'})
RETURN m
WHERE子句还可以是正则表达式匹配、数值比较和查看列表中是否存在某个值
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
WHERE =~ 'K.+' OR > 2000 OR 'Neo' IN
RETURN p, r, m
一个高级用法是模式可以用作谓词。在MATCH
扩展匹配模式的数量和形状的地方,模式谓词限制当前结果集。它只允许满足指定模式的路径通过。正如我们可以预期,采用NOT
只允许传递那些不符合指定的模式的路径。
# 在这里,我们找到演员,因为他们建立了ACTED_IN关系,但随后跳过了DIRECTED任何电影中的那些演员
MATCH (p:Person)-[:ACTED_IN]->(m)
WHERE NOT (p)-[:DIRECTED]->()
RETURN p, m
- Cypher中最简单的表达式是字面值(数字、字符串、数组和映射),任何节点、关系和映射的各个属性都可以用点语法,比如,还可以使用下标检索单个元素或数组切片,比如names[0]和movies[1…-1],函数也是一个表达式,比如
length(array)
,toInteger('12')
,substring('2014-07-01', 0, 4)
和coalesce(, 'n/a')
。 - 默认情况下,表达式本身将用作列的标签,在许多情况下,您希望使用
expression AS alias
. 随后可以使用别名来引用该列。。
MATCH (p:Person)
RETURN
p,
AS name,
toUpper(),
coalesce(, 'n/a') AS nickname,
{name: , label: head(labels(p))} AS person
- 如果希望只显示唯一的结果,可以在RETURN后面加上关键字DISTINCT
MATCH (n)
RETURN DISTINCT labels(n) AS Labels
- 在许多情况下,我们希望在遍历图中的模式时对遇到的数据进行聚合或分组。在 Cypher 中,聚合发生在
RETURN
计算最终结果的子句中。许多常见的聚集功能的支持,例如count
,sum
,avg
,min
,和max
MATCH (:Person)
RETURN count(*) AS people
-
使用
ORDER BY expression [ASC|DESC]
子句进行排序。表达式可以是任何表达式,只要它可以从返回的信息中计算出来。使用ORDER BY expression [ASC|DESC]
子句进行排序。表达式可以是任何表达式,只要它可以从返回的信息中计算出来。 -
一个非常有用的聚合函数是
collect()
,它将所有聚合值收集到一个列表中。这在许多情况下非常有用,因为在聚合时不会丢失任何细节信息。collect()
非常适合检索典型的父子结构,其中每行返回一个核心实体(parent、root或head)及其所有相关信息,这些信息位于用collect()
. 这意味着无需为每个子行重复父信息,也无需运行n+1
语句来分别检索父行及其子行。创建的列表collect()
可以从使用 Cypher 结果的客户端使用,也可以直接在具有任何列表函数或谓词的语句中使用。
MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN AS movie, collect() AS cast, count(*) AS actors
- 如果要合并具有相同结果结构的两个语句的结果,可以使用
UNION [ALL]
.
MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie)
RETURN AS name, type(r) AS type, AS title
UNION
MATCH (director:Person)-[r:DIRECTED]->(movie:Movie)
RETURN AS name, type(r) AS type, AS title
相当于
MATCH (actor:Person)-[r:ACTED_IN|DIRECTED]->(movie:Movie)
RETURN AS name, type(r) AS type, AS title
- WITH关键字
在 Cypher 中,可以将语句片段链接在一起,类似于它在数据流管道中的完成方式。每个片段都处理前一个片段的输出,其结果可以输入下一个片段。 只有在WITH
子句中声明的列在后续查询部分中可用。
该WITH
子句用于组合各个部分并声明哪些数据从一个部分流向另一个部分。 WITH
与RETURN
子句类似。不同之处在于该WITH
子句不会完成查询,而是为下一部分准备输入。表达式、聚合、排序和分页的使用方式与RETURN
子句中的使用方式相同。唯一的区别是所有列都必须有别名。
MATCH (person:Person)-[:ACTED_IN]->(m:Movie)
WITH person, count(*) AS appearances, collect() AS movies
WHERE appearances > 1
RETURN , appearances, movies
- 索引
在图数据库中使用索引的主要原因是为了找到图遍历的起点。一旦找到该起点,遍历就依赖于图内结构来实现高性能。可以随时添加索引。
# 创建一个索引以加快在数据库中按名称查找演员的速度
CREATE INDEX FOR (a:Actor) ON ()
# 在大多数情况下,查询数据时不需要指定索引,因为将自动使用适当的索引
MATCH (actor:Actor {name: 'Tom Hanks'})
RETURN actor
复合索引是对具有特定标签的所有节点的多个属性的索引。
# 在所有标有Actor和 且同时具有name和born属性的节点上创建一个复合索引
CREATE INDEX FOR (a:Actor) ON (, )
我们可以检查我们的数据库以找出定义了哪些索引。我们通过调用内置过程来做到这一点:
CALL
YIELD description, tokenNames, properties, type;
- 使用约束
约束用于确保数据符合域的规则。例如:“如果一个节点的标签为Actor
,属性为name
,则 的值name
在所有具有Actor
标签的节点中必须是唯一的”。
为了创建一个约束以确保我们的数据库永远不会包含多个带有标签Movie
和title
属性的节点,我们使用 IS UNIQUE 语法
CREATE CONSTRAINT ON (movie:Movie) ASSERT IS UNIQUE
我们可以检查我们的数据库以找出定义了哪些约束。我们通过调用内置过程来做到这一点:
CALL
- 查询某个标签的结点的所有属性
MATCH (n:Test) RETURN distinct keys(n)