Neo4j之Cypher语句

本文为图数据库 Neo4j 查询语言 Cypher 学习笔记,包括 MATCH RETURN CREATE DELETE REMOVE MERGE 语句的基本用法。

MATCH

MATCH 语句用于查询,常与 WHERE 连用,与 SQL 语句中的 SELECT ... FROM ... WHERE 用法相似。

查找节点

查找所有节点

以下命令将返回所有节点,若在 Neo4j Browser 下,则会返回整个图,包括节点和关系,与 SQL 中的 SELECT * 类似。

1
2
MATCH (n) 
RETURN n

注:

  1. 分行并非必要;

  2. n 相当于一个假定变量,大小写敏感,前后不一致将会导致变量未定义错误,同时,因为 n 是一个假定变量,因此在查询语句的书写时和程序中设置变量一样可以使用一个更具体的描述词,而不是使用通常的变量名 n x y ,增强查询语句的可读性;

  3. 括号是必要的,作为模式的表示方式,节点是最简单的模式;

  4. 关键字的大小写不敏感,与 SQL 类似,大小写混用并不会出错,但并不建议混用。

查找指定标签节点

以下命令返回 Lable 标签下的所有节点。

1
2
MATCH (n:Lable)
RETURN n

查找连接节点

以下命令返回与带 Label 标签,属性 name 值为 a 的节点相连接的所有节点。

1
2
MATCH (Lable{name:'a'})--(n)
RETURN n

若要限定返回节点的标签 Lable1,可在变量 n 后做限定。

1
2
MATCH (Lalbe{name:'a'})--(n:Lable1)
RETURN n

关系表示符可指定方向:

  • -- :任意方向;

  • --> :指向其他节点;

  • <-- :指向自身。

查找关系

查找关系类型

以下命令返回连接 Lable 标签下 name 属性分别为 a, b 的两个节点的关系类型。

1
2
MATCH (:Lable{name:'a'})-[r]-(:Lable{name:'b'})
RETURN TYPE(r)

TYPE 大小写不敏感。

若两个节点间没有关系,则不会做任何改变,也无返回值。

若要指定关系方向,可将第一句改为以下两种情况:

1
2
MATCH (:Lable{name:'a'})<-[r]-(:Lable{name:'b'})
MATCH (:Lable{name:'a'})-[r]->(:Lable{name:'b'})

查找指定关系

以下命令返回关系类型为 RELAY 的节点及其关系。

1
2
MATCH (a)-[:RELAY]-(b)
RETURN *

匹配多个关系可用管道符 | 连接,如:

1
MATCH (a)-[:RELAY|:RELAY1]-(b)

RETURN

RETURN 语句设定返回类型,如上面提到的返回节点,返回关系,返回节点的特定属性。已上一个命令为例,返回的是所有节点和关系,相当于:

1
2
MATCH (a)-[r:RELAY]-(b)
RETURN a, b, r

若要返回节点属性 name,可写作

1
2
MATCH (a)-[:RELAY]-(b)
RETURN a.name

返回关系类型上面已提及,不重复描述。

CREATE

创建节点

若要查看创建节点的结果,需用 RETURN 语句返回,实际上以下其他命令也是如此,下面不再列出 RETURN 语句除非必要。否则仅会输出提示节点的创建数量、属性的设置数量、标签的创建数量。

创建空节点

以下命令创建一个空节点。

1
CREATE (n)

若要创建多个节点,可用逗号分隔。

1
CREATE (n), (m)

创建带标签的节点

以下命令创建一个带标签的节点。

1
CREATE (n:Lable)

若要创建多个标签,可紧随其后。

1
CREATE (n:Lalbe:Lable1)

创建带属性节点

以下命令创建一个带属性节点,并指定 name name1为属性名, a b 为属性值

1
CREATE (n:Lable{name:'a', name1:'b'})

创建关系

创建关系首先要使用 MATCH 语句匹配到关系的起点和终点。以下命令先匹配到 a b 两个节点,然后建立两个节点间的关系 RELAY

1
2
MATCH (a:Lable{name:'a'}), (b:Lable{name:'b'})
CREATE (a)-[:RELAY]->(b)

注:

  1. 关系的创建与查询时不同,必须指明关系方向,仅允许创建有方向的关系;

  2. 关系创建时必须设定关系名;

  3. 此匹配节点语句并不是最佳,会弹出 Warning 提示建议使用 OPIONAL MATCH 优化查询速度,此处不做探讨。

DELETE

DELETE 语句用于删除节点或关系。需要先查找到节点或者关系,实际上在仅对节点和关系的删除上只要把 MATCH 中的 RETURN 语句换做 DELETE 语句就可以完成删除。

有一点不同的是,DELETE 语句可以在删除节点的同时删除掉与之的关系,使用 DETACH DELETE, 如:

1
2
MATCH (n:Lable{name:'a'})
DETACH DELETE n

以下命令可以删除所有节点和关系,在学习试验的小数据中很有用:

1
2
MATCH (n)
DETACH DELETE n

REMOVE

移除节点属性

Neo4j 不允许属性值为 null,所以移除节点属性也可说是用于删除该属性。以下命令移除所有节点的 name 属性。

1
2
MATCH (n)
REMOVE n.name

REMOVE 语句无法使用一条命令删除所有属性,需要使用 SET 语句,此处不做探讨。

移除节点标签

以下命令移除节点 a 标签 Lable,移除多个标签和 CREATE 语句类似。

1
2
MATCH (n{name:'a'})
REMOVE a:Lable

MERGE

MERGE 命令用于在模式匹配不成功时创建该模式,类似先通过 MATHCH 进行模式查找,再用 CREATE 进行模式创建。相比后一种方式,MERGE 命令更简洁,但无法进行部分匹配,一旦匹配表达式的某项不满足,整个模式都将被创建。

归并节点

归并节点标签

以下命令查找是否存在标签为 LABEL 的节点,若不存在,则创建一个标签为 LABEL 的节点,若存在,则不会做出改动。

1
MERGE (n:LABEL)

归并节点属性

以下命令查找是否存在 name 属性为 n 的节点,若不存在,则创建一个 name 属性为 n 的节点,若存在,则不做出改动。

1
MERGE (n{name:'n'})

要匹配多个属性及其对应的值可用逗号隔开,如:

1
MERGE (n{name1:'n', name2:'m'})

在上面这条语句的情况下,只有 name1name2 属性同时满足匹配条件时才不会对图数据库做出改动,只要不存在有一个节点同时满足上述两个条件,则会创建新的节点,即前面提到的 MERGE 语句无法实现部分归并。

从已有属性归并节点

以下命令从已有的 LABEL1 标签下的节点查找其节点属性 p1 ,并归并出 LABLE2 标签的节点,新节点的属性视为 p2 ,从而不重复创建。

1
2
MATCH (n:LABEL1)
MERGE (m:LABEL2{p2:n.p1})

具体示例可查看官方手册的 MERGE 章节,举个简单的例子假设图数据库中已有几名学生的信息作为节点,学生的信息包括其籍贯,通过上面的命令即将学生视为标签 LABEL1,籍贯视为属性 p1,并将籍贯形成新的节点标签 LABEL2,以上命令就相当于不重复地列出学生的籍贯并一一建立新节点,并为新籍贯节点创建的属性视为 p2 ,如果图数据库中已有籍贯相同的节点,则不会再被创建,保证了唯一性。这在从已有数据分离出一些较小的数据项时很有用。

参考资料