前言
结点
标签
关系和关系类型
属性
路径
模式
索引和约束
路径匹配
匹配任意结点
匹配路径
匹配标签
指定约束
匹配关系
变长路径匹配
在学习Neo4j之前,我们要先了解Neo4j的一些基本概念,这样我们才能更容易理解Cypher语句以及设计自己的图数据库,如果学习过图相关知识理解起来也比较简单。这里结合The Neo4j Getting Started Guide v4.3的例子(下图)来讲述一下。
下面的图片所描述的是一个图,有点像ER图,这个图是由若干个结点和连接这些结点的有向边组成的。
结点常用来表示某些实体。如上图所示,Tom Hanks,Robert Zemeckis和Forrest Gump都是实体,用结点表示。一个结点也可以构成一个图。
将实体的某些共同特点抽象出来,我们就可以把实体分为若干个类,这有点像面向对象的思想,结点就是对象,标签就是类名。如上图所示,Tom Hanks和Robert Zemeckis都是人,所以我们给它个Person标签,Forrest Gump是一部电影,所以给他Movie标签。
两个结点之间存在的有向边我们称它为关系。关系是有方向的,比如上图的两个关系ACTED_IN和DIRECTED,同时ACTED_IN和DIRECTED也叫做关系类型,从图中可以看出Tom Hanks出演了Forrest Gump这部电影,而Robert Zemeckis是这部电影的导演,如果这个关系反过来或者是双向的那么逻辑上就讲不通了。
结点和关系都有属性。属性是用来描述结点和关系的相关信息的,为键值对的形式。比如属性name值为Tom Hanks的这个人结点,他出生于1956年(born=1956),属性name值为Robert Zemeckis的这个电影结点,发行于1994年(released=1994),Tom Hanks与Robert Zemeckis的饰演关系ACTED_IN中,Tom Hanks充当Forrest这个角色(roles=['Forrest'])。
路径由若干个结点和它们之间的关系组成。从Tom Hanks到Forrest Gump这两个实体组成的路径如下图。
上图的路径长度为1,路径的方向是从Tom Hanks到Forrest Gump。路径的长度可以为0,并且也能自己指向自己,如下图。
这里的模式指的是数据库的概念模式,是数据库的逻辑表示,包括每个数据的逻辑定义以及数据间的逻辑联系。Neo4j中是否要规定概念模式由开发者自行决定,开发者无需预先定义架构,也不一定要创建索引和约束,不像SQL,Neo4j只需创建节点、关系和属性,在需要的时候再引入索引和约束也可以。
索引和约束的定义与SQL的类似,索引用来提高查询的性能,约束用于确保数据符合规则。
由于后面会先学Cypher从句,这里先讲一下关于路径匹配模式的东西,后面学从句的时候能更容易看得懂整个句子表达的意思。
Neo4j使用一个圆括号括住一个变量来匹配结点:
(a)
(a)表示匹配一个任意类型的结点,然后节点信息存在a中,a为一个变量。在后面路径的匹配中这个变量可写可不写,当你需要用变量存储路径对应位置的信息时就可以写。
路径匹配实际上是按你给出来的形式来匹配路径
Neo4j使用短横线和小于号或大于号表示一个方向,两个短横线表示匹配任意关系,比如:
(a)-->(b)
(a)-->(b)表示匹配任意两个结点和它的关系(关系方向为一个结点到另一个结点)组成的长度为1的路径,节点信息保存在a和b中,我们可以用图来画出这种关系。
还有一种复杂一点的匹配
(a)-->(b)<--(c)
匹配的模式如下图
如果不需要中间那个结点的信息的话我们可以写成
(a)-->()<--(c)
我们用冒号加标签名来表示一个标签
(a:User)-->(b)
这时匹配的是标签为User的结点到任意节点长度为1的路径。当然我们可以使用多标签或者不使用变量来存放节点信息。使用多标签表示匹配包含给出的所有标签的结点。
(a:User:Admin)-->(b)
(:User:Admin)-->(b)
我们可以给结点添加一些属性约束,从而达到where子句的效果
(a {name: 'Andy'})-->(b)
这里匹配属性name为Andy的结点与任意结点长度为1的路径。
前面我们匹配的是任意的关系,我们还可以指定关系类型
(a)-[r:REL_TYPE]->(b)
这里REL_TYPE就是关系类型,匹配任意关系类型为REL_TYPE的长度为1的路径,关系信息存在变量r中。关系只能有一种类型,但我们可以匹配多种类型的关系,用竖线|隔开,表示满足给出关系中的任一个就能匹配。
(a)-[r:TYPE1|TYPE2]->(b)
不需要使用关系信息时可以省略变量r。
(a)-[:REL_TYPE]->(b)
前面我们匹配的都是长度为1的路径,我们还能匹配不定长的路径。比如匹配长度为2的路径,可以这样写
(a)-[*2]->(b)
这样写等价于
(a)--()-->(b)
表示匹配任意长度为2的路径。
我们还能匹配给定长度范围的路径。比如匹配任意路径长度为3到5(包括3和5)的路径:
(a)-[*3..5]->(b)
匹配长度大于3(包括3)的路径
(a)-[*3..]->(b)
匹配长度小于5(包括5)的路径
(a)-[*..5]->(b)
匹配任意长度的路径
(a)-[*]->(b)
此外,我们还能指定路径的关系类型,比如
(a)-[r:REL_TYPE*1..2]->(b)
表示匹配长度为1到2并且类型为REL_TYPE的路径。