前言
大家好,我是半虹
这篇文章主要讲解 Neo4j 查询语言 Cypher
正文
0、连接终端
正如关系型数据库使用 SQL 管理数据,图数据库 Neo4j 使用 Cypher 完成对数据的增删改查操作
对于 Neo4j 而言,既可以在图形化交互界面执行 Cypher,又可以在命令行交互终端执行 Cypher
两者的不同仅仅在于交互方式的不同,执行 Cypher 的方式和效果是完全一样的
打开图形化交互界面的方法非常简单,只需在浏览器打开预先设置好的地址即可
打开命令行交互终端的方法也很简单,只需运行 bin 目录下的 cypher-shell 工具即可
1、基本概念
图数据库是用来存储图结构的,对于一个图来说,最重要的元素当然是点和边
这两者分别对应着图数据库中最重要的两个实体,节点和关系
除此之外,想要学习图数据库,还必须了解图数据库中的一些基本概念
实体(entity)
- 每个实体有且仅有一个唯一标识(id)
- 每个实体可以有零个或多个属性(property)
- 实体包括节点,对应图结构中的点,每个节点可以有零个或多个标签(label)
- 实体包括关系,对应图结构中的边,每个关系有且仅有一个关系类型(relationship type)
属性(property)
- 一个键值对,每个实体可以有零个或多个属性
- 属性值既可以是标量类型,也可以是组合类型
标记(token)
- 非空字符串,用于表示属性键、标签、关系类型
- 属性键:在一个节点或关系中,属性键是唯一的
- 标签:用于对节点分组,每个节点可以有零个或多个标签,有相同标签的节点属于同一组
- 关系类型:每个关系有且仅有一个关系类型,不同关系可以有相同的关系类型
路径(path)
- 由开始节点到结束节点之间的实体构成的有序集合
2、基本语法
正如 SQL 定义关键字表示不同的操作,Cypher 也有定义关键字,这些关键字不区分大小写
由于篇幅原因,这里只介绍比较常用的几个,更高级的操作可以等后面需要的时候再去了解
关键字 | 作用 |
MATCH |
查询 |
WHERE |
匹配 |
RETURN |
返回 |
CREATE |
创建节点和关系 |
DELETE |
删除节点和关系 |
SET |
修改节点标签,修改节点和关系的属性 |
REMOVE |
删除节点标签,删除节点和关系的属性 |
此外 Cypher 也有定义函数,这些函数作用多样,比如用于获取节点或关系的属性等等
这里介绍一些常用的函数,如果需要了解其它的函数,可以在官网上找到更详细的文档
查询函数 | 作用 |
id() |
返回节点或关系的唯一标识 |
labels() |
返回节点标签 |
type() |
返回关系类型 |
keys() |
返回节点或关系的属性键 |
properties() |
返回节点或关系的属性 |
好了,介绍完基本语法后,下面开始进入实战
(0)变量(variable)
变量用于对搜索模式进行命名,以便于在后续查询中进行引用
在一个查询中,变量并不是必须的,如果无需进行引用,那么就不需要有变量
MATCH (n) RETURN n;
这是最简单的一条语句,其作用是查询图数据库中的所有节点并返回
(1)节点(node)
在 Cypher 中,节点用小括号表示,其中 Variable
是变量,便于后续对节点进行引用
Label
是节点标签,标签之间用冒号隔开,Key:Value
是节点属性,属性之间用逗号隔开
(Variable:Label1:Label2:...{Key1:Value1,Key2:Value2,...})
创建节点
// 创建一个普通节点 CREATE (n) RETURN n;
// 创建一个带标签的节点 CREATE (n:Person) RETURN n;
// 创建一个带属性的节点 CREATE (n{name:'Alice'}) RETURN n;
// 创建一个带标签带属性的节点 CREATE (n:Person{name:'Alice'}) RETURN n;
查询节点
// 查询所有节点 MATCH (n) RETURN n; // 查询所有节点的唯一标识 MATCH (n) RETURN id(n);
// 查询带标签的节点 MATCH (n:Person) RETURN n; // 等价于 MATCH (n) WHERE n:Person RETURN n;
// 查询带属性的节点 MATCH (n{name:'Alice'}) RETURN n; // 等价于 MATCH (n) WHERE n.name = 'Alice' RETURN n;
// 查询带标签带属性的节点 MATCH (n:Person{name:'Alice'}) RETURN n; // 等价于 MATCH (n) WHERE n:Person AND n.name = 'Alice' RETURN n;
(2)关系(relationship)
在 Cypher 中,关系用中括号表示,其中 Variable
是变量,便于后续对关系进行引用
RelationshipType
是关系类型,Key:Value
是关系属性,属性之间用逗号隔开
关系表示两个节点之间的有向连接,其中 StartNode
是开始节点,EndNode
是结束节点
StartNode-[Variable:RelationshipType{Key1:Value1,Key2:Value2,...}]->EndNode
创建关系
// 创建不带属性的关系 MATCH (m:Person),(n:Person) WHERE m.name='Alice' AND n.name='Bob' CREATE (m)-[r:Friend]->(n) RETURN r;
// 创建带有属性的关系 MATCH (m:Person),(n:Person) WHERE m.name='Alice' AND n.name='Bob' CREATE (m)-[r:Friend{year:100}]->(n) RETURN r;
查询关系,分为三种,--
表示无向关系,-->
和 <--
表示有向关系
// 查询不带类型不带属性的无向关系 MATCH (m:Person{name:'Alice'})-[r]-(n:Person{name:'Bob'}) RETURN r; // 查询带有类型不带属性的无向关系 MATCH (m:Person{name:'Alice'})-[r:Friend]-(n:Person{name:'Bob'}) RETURN properties(r); // 查询不带类型带有属性的无向关系 MATCH (m:Person{name:'Alice'})-[r{year:100}]-(n:Person{name:'Bob'}) RETURN type(r); // 查询带有类型带有属性的无向关系 MATCH (m:Person{name:'Alice'})-[r:Friend{year:100}]-(n:Person{name:'Bob'}) RETURN m, r, n;
// 查询不带类型不带属性的有向关系 MATCH (m:Person{name:'Alice'})-[r]->(n:Person{name:'Bob'}) RETURN r; // 等价于 MATCH (n:Person{name:'Bob'})<-[r]-(m:Person{name:'Alice'}) RETURN r;
// 查询特定关系类型的关联节点 MATCH (m:Person{name:'Alice'})-[r:Friend]->(n) RETURN n; // 查询多种关系类型的关联节点,只需匹配一个就算匹配成功 MATCH (m:Person{name:'Alice'})-[r:Friend|:Know]->(n) RETURN n; // 查询匹配多种关系的关联节点 MATCH (m:Person{name:'Alice'})-[:Friend]->(x)<-[:Friend]-(n:Person{name:'Bob'}) RETURN x;
(3)路径(path)
变长路径
// 匹配任意长度的路径 MATCH (m)-[r*]->(n) RETURN m, r, n;
// 匹配路径长度等于 3 的路径 MATCH (m)-[r*3]->(n) RETURN m, r, n;
// 匹配路径长度大于等于 2 的路径 MATCH (m)-[r*2..]->(n) RETURN m, r, n;
// 匹配路径长度小于等于 5 的路径 MATCH (m)-[r*..5]->(n) RETURN m, r, n;
// 匹配路径长度大于等于 2 且小于等于 5 的路径 MATCH (m)-[r*2..5]->(n) RETURN m, r, n;
路径变量
// 用路径变量进行引用 MATCH p=(m)-[r*]->(n) RETURN p;
(4)删除节点和关系
// 删除所有节点,注意这条语句只能删除没有关系连接的节点 MATCH (n) DELETE n;
// 删除所有关系 MATCH ()-[r]-() DELETE r;
(5)修改节点和关系
// 修改节点属性,有则修改,无则增加 MATCH (n) WHERE id(n) = 7 SET n.name = "Jack" RETURN n; // 删除节点属性 MATCH (n) WHERE id(n) = 7 REMOVE n.name RETURN n;
// 修改节点标签,有则修改,无则增加 MATCH (n) WHERE id(n) = 7 SET n:Person RETURN n; // 删除节点标签 MATCH (n) WHERE id(n) = 7 REMOVE n:Person RETURN n;
// 修改关系属性,有则修改,无则增加 MATCH (m)-[r]->(n) WHERE id(m) = 13 AND id(n) = 14 SET r.year = 10 RETURN r; // 删除关系属性 MATCH (m)-[r]->(n) WHERE id(m) = 13 AND id(n) = 14 REMOVE r.year RETURN r;