什么是Neo4j?
Neo4j是一个由Java编写的高性能图数据库,它将结构化的数据存在网络上而不是表中。
在关系型数据库中,我们表示多对多的关系需要一张中间表连接,当关系变得复杂时,就需要多张中间表,这样便使得数据表间关系复杂且耦合性强,不易维护修改。为了提供用于遍历大量数据的适当性能,应运而生出了图数据库。
数据模型:
每个数据抽象成对象用一个圆圈结点来表示,属性是键值对,关系用方向连接且必须有方向(单或多),一个数据节点也可以指向自己。
Neo4j安装:
https://www.w3cschool.cn/neo4j/neo4j_zip_environment_setup.html
Cypher语法:
-
读语句:
MATCH:用指定的模式检索数据库。
// 返回数据库中所有节点
MATCH (n) RETURN n
括号中的节点变量可以任意命名
1.1.1:匹配查询:
// 其中括号内的是变量名,我们可以自定义命名
MATCH (movie:MOVIE) RETURN (movie:title)
1.1.2:查询关联节点:
// 查询与movie相关联的节点并且name属性是Tom,返回movie节点的title属性。
// 通俗讲就是查询Tom参演的电影并且返回这些电影的标题
MATCH ({name: 'Tom'})--(movie) RETURN movie.title
// 返回与Tom相关(标签是Person)的标签是Movie的所有节点(movie)的标题
MATCH (:Person{name: 'Tom'})--(movie:Movie) RETURN movie.title
// 返回Tom指向的电影的标题
MATCH(:Person{name:'Tom'})-->(movie) RETURN movie.title
1.1.3:关系查询:
// 查询Tom与movie结点间的所有关系,r在这里指某种关系
MATCH (:Person{name:'Tom'})-{r}->(movie) RETURN type(r)
// 查询黑客帝国的参演者并绘制关系图
MATCH(walls:Movie{title:'The Matrix'})<-[:ACTED_IN]-(actor) RETURN actor.name,walls
// 匹配多种关系
MATCH(movie{title:'The Matrix'})<-[:ACTOR_IN|:DIRECTED]-(person) RETURN person,movie
// 匹配关系并返回关系的属性
MATCH (sets{title:'The Matrix'})<-[r:ACTED_IN]-(actor) RETURN r.roles
// 多关系查询
// 返回Tom所参演的电影名称与导演该部电影的导演名称
MATCH(actor{name:'Tom'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director) RETURN movie.title, director.name
// 查询与Tom参演过并存在1~3层关系的电影
MATCH (actor{name:'Tom'})-[:ACTED*1..3]-(movie:MOVIE) RETURN movie
1.1.4:查询路径:
// 查询与Tom相关两跳的数据
MATCH P = (TOM{name:'Tom Hanks'})-[r*2]-() RETURN P
// 查询最短路径
MATCH P = shortestPath((tom{name:'Tom Hanks'})-[*]-(Steve{name:'Steve Zahn'})) RETURN P
1.1.5:WHERE:
// 用WHERE限定查询条件
MATCH ()-[r]-() WHERE id(r) = 0 RETURN r
// IN语句限定范围
MATCH (n) WHERE id(n) IN [0,3,5] RETURN n
1.1.6:OPTIONAL MATCH
用于搜索模式中描述的匹配项,对于找不到的用null代替。
// 查询指向a元素的x节点,没有则返回null
MATCH (a:MOVIE{title:'The Matrix'}) OPTIONAL MATCH (a)-->(x) RETURN x
// 可选关系查询
MATCH (a:Movie {title: 'The Matrix'}) OPTIONAL MATCH (a)<-[r:ACTED_IN]-() RETURN r
WHERE:在MATCH中添加约束,可以用WITH来一同过滤结果
2.1.1:布尔运算:
// 查询年份大于1990年小于2000年的电影标题,多个关系用and连接
MATCH(node:Movie) WHERE node.released > 1990 AND node.released < 2000 RETURN node.title
2.1.2:exists:
// 检查存在title属性的结点数据
MATCH (n) WHERE exists(n.title) RETURN n
2.1.3:字符串匹配:
该匹配模式大小写敏感。
// 查询name以Tom开头的结点
MATCH (n) WHERE n.name STARTS WITH 'Tom' RETURN n
// 查询name以Hanks为结尾的结点
MATCH (n) WHERE n.name ENDS WITH 'Hanks' RETURN n
// 查询包含某些字符的结点
MATCH (n) WHERE n.name CONTAINS 'bin' RETURN n
// Not匹配
MATCH (n) WHERE NOT n.name ENDS WITH 's' RETURN n
2.1.4:正则表达式:
Cypher支持正则表达式的匹配,使用 =~'regexp'来进行正则表达式匹配
// 正则表达式匹配
MATCH (n) WHERE n.name=~'Tom.*' RETURN n
// 正则表达式非大小写敏感
MATCH (n) WHERE n.name=~'(?i)TOM.*' RETURN n
2.1.5:空值判断与逻辑组合:
// 匹配节点name属性为Keanu Reeves或name属性为空的节点,会将电影节点与人物节点统统返回
MATCH(n) WHERE n.name = 'Keanu Reeves' OR n.name IS NULL RETURN n ORDER BY n.name
RETURN:返回匹配模式中的节点与数据关系
RETURN语句作为返回,不仅可以返回模式匹配到的结果,还可以返回布尔值,字符串等表达式
3.1.1:用特殊字符作为变量名称:
// 以空格等特殊变量字符作为变量名,使用反引号``引起来
MATCH (`Var Space`) WHERE `Var Space`.name = 'Tom' RETURN `Var Space`
3.1.2:列别名:
// AS为匹配到的数据起别名
MATCH (a{name:'Tom'}) RETURN a.born AS bornyear
3.1.3:唯一查询:
// 返回出生年份为1960不存在重名的节点数据
MATCH (a{born:1960}) RETURN DISTINCT a.name
CREATE:创建图元素,节点与关系,索引等
创建两个节点的关系必须有箭头指向。
// 创建带有多个标签的节点
CREATE (n:Person:Swedish)
// 创建关系并设置属性
CREATE (n:Person{name:'Node A'}), (m:Person{name:'Node B'})
MATCH (a:Person), (b:Person) WHERE a.name = 'Node A' AND b.name = 'Node B'
CREATE (a)-[r:RELTYPE{name:'relation'}]->(b)
RETURN r
// 创建完整路径
CREATE p = (andress{name:'andress'}) -[:WORKS_AT]->(neo)<-[:WORKS_AT]-(michael{name:'Michael'}) RETURN p
// 创建索引
CREATE INDEX ON :Person(name)