neo4j部分文档学习
最后更新时间:
写在前面
记录一下跟着文档学习neo4j,里面会牵涉到一些在扫链子当中需要用的重要概念
MATCH
用于去匹配指定的模式
以下图中的样本图为例
基本的结点搜寻
获取所有结点
1
2MATCH (n)
RETURN n获取所有带标签的结点
1
2MATCH (movie:Movie)
RETURN movie.title相关结点
标志
--
代表中一种关联,但是忽视关联的方向和类型1
2MATCH (director {name: 'Oliver Stone'}) -- (movie)
RETURN movie.title匹配标签
为了利用标签模式来限制结点,在模式结点上加入标签语法
1
2MATCH (:Person {name: 'Oliver Stone'}) -- (movie:Movie)
RETURN movie.title
基本关系概念
外向关系
当关系表现出倾向性,通过
-->
或<--
来表示1
2MATCH (:Person {name: 'Oliver Stone'}) --> (movie)
RETURN movie.title直接关系和变量
可以通过一个变量来过滤关系的属性或者返回关系
1
2MATCH (:Person {name: 'Oliver Stone'}) -[r]-> (movie)
RETURN type(r)该语句可以返回所有从Oliver发出的有向关系的类型
匹配关系类型
当你知道想要匹配的关系类型时,通过
:关系类型
来指定1
2MATCH (wallstreet:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)
RETURN actor.name匹配多种关系类型
可以将多种关系类型用
|
连接起来,表示匹配多种关系类型之一1
2MATCH (wallstreet:Movie {title: 'Wall Street'})<-[:ACTED_IN|DIRECTED]-(actor)
RETURN actor.name匹配关系类型并使用变量
如果想要用变量来表示关系,且想指定想要的关系类型,都加上去即可
1
2MATCH (wallstreet {title: 'Wall Street'})<-[r:ACTED_IN]-(actor)
RETURN r.role
关系深度
在单一模式下,关系只会被匹配一次
关系类型中包含非常见字符
有时数据库关系类型中包含非常见类型,比如空格。这时可以通过反引号`来引用
例如上图中的红线,可以如下查询
1
2MATCH (n {name: 'Rob Reiner'})-[r:`TYPE INCLUDING A SPACE`]-> ()
RETURN type(r)多重关系
多个关系可以通过使用多个
()--()
形式的表达式来表示,或者直接连起来1
2MATCH (chalie {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(direcotr)
RETURN movie.title, director.name变长关系
需要多个
relationship->node
模式表示的结点可以通过-[:TYPE*minHops..maxHops]->
来表示,其中minHops
和maxHops
是可选的,默认分别是1和无穷大。当没有给定界限时,点号可以忽略。当只有一个界限时点好也可以忽略,表示的是一个固定长度的模式1
2MATCH (charlie {name: 'Charlie Sheen'}) -[:ACTED_IN*1..3]-(movie:Movie)
RETURN movie.title变长多种关系
变长关系和多种关系可组合。这样的话变长范围适用于所有结合的关系类型
1
2MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN||DIRECTED*2]-(person:Person)
RETURN person.name可变长度关系的关系变量
当在两节点之间的连接是可变长度时,返回的构成连接的关系列表可以如下语法表示
1
2MATCH p = (actor {name: 'Charlie Sheen'})-[:ACTED_IN*2]-(co_actor)
RETURN relationships(p)匹配可变长路径上的属性
变长关系上的属性意味着在路径上的所有关系都必须拥有指定的属性值。例如下图所示
1
2
3MATCH p = (charlie:Person)-[* {blocked:false}]-(martin:Person)
WHERE charlie.name = 'Charlie Sheen' AND martin.name = 'Martin Sheen'
RETURN p这将返回所有在 ‘Charlie Sheen’ 和 ‘Martin Sheen’之前的路径且满足属性
blocked
为false
零长路径
使用下限为0的变长路径意味着两个变量可以指向同一结点。如果两节点之间的路径长度为0的话,它们就被定义为同一结点。注意到当匹配零长路径时结果即使未使用关系类型也能匹配到一个结果(即自身?)
1
2MATCH (wallstreet:Movie {title: 'Wall Street'})-[*0..1]-(x)
RETURN x命名路径
当想要在模式图中返回或过滤一条路径,可以引入命名路径
1
2MATCH p = (michael {name: 'Michael Douglas'})-->()
RETURN p匹配有界关系
当你的模式包含有界关系,而关系中并没有明确方向,Cypher会尝试双向匹配关系
1
2
3MATCH (a)-[r]-(b)
WHERE id(r) = 0
RETURN a,b该语句会返回两个连接节点,一个是开始结点,另一个是终止结点
最短路径
单一最短路径
使用函数
shortestPath
1
2
3
4
5MATCH
(martin:Person {name: 'Martin Sheen'})
(oliver:Person {name: 'Oliver Stone'})
p = shortestPath((martin)-[*..15]-(oliver))
RETURN p这意味着:只要路径长度最大不超过15,就会在其中寻找满足的最短路径。在括号中定义了开始结点,连接关系和终止结点。在寻找最短路径时典型的描述关系的条件如关系类型,最大跳数和方向都会用上。如果在
shortestPath
匹配之后跟着where
语句,相应的限定都会包含在寻找过程中。如果谓词是none()
或all()
,同理。单一最短路径,带上谓词
在最短路径模式中用上谓词
WHERE
也会在决定最短路径前进行评估1
2
3
4
5
6MATCH
(charlie:Person {name: 'Charlie Sheen'}),
(martin:Person {name: 'Martin Sheen'}),
p = shortestPath((charlie)-[*]-(martin))
WHERE none(r IN relationships(p) WHERE type(r) = 'FATHER')
RETURN p不考虑父子关系
所有最短路径
寻找两节点间所有最短路径
1
2
3
4
5MATCH
(martin:Person {name: 'Martin Sheen'} ),
(michael:Person {name: 'Michael Douglas'}),
p = allShortestPaths((martin)-[*]-(michael))
RETURN p
通过id获得节点或关系
id寻找节点
在谓词中使用
id()
函数可以通过id来寻找节点1
2
3MATCH (n)
WHERE id(n) = 0
RETURN nid获取关系
在谓词中使用
id()
函数可以通过id来寻找关系1
2
3MATCH ()-[r]->()
WHERE id(r) = 0
RETURN rid寻找多个节点
通过利用
IN
可以指定选择多个节点1
2
3MATCH (n)
WHERE id(n) IN [0,3,5]
RETURN n
RETURN
定义查询结果集都有什么
返回节点
直接列举在
RETURN
陈述句当中即可1
2MATCH (n {name: 'B'})
RETURN n返回关系
同理
1
2MATCH (n {name: 'A'})-[r:KNOWS]->(c)
RETURN r返回属性
利用点分隔符
1
2MATCH (n {name: 'A'})
RETURN n.name返回所有元素
同样支持统配符
*
来返回 所有结点、关系和路径1
2MATCH p = (a {name: 'A'})-[r]->(b)
RETURN *这将返回p a r b
非常见字符变量
为了引进并不是由英文字母表中元素构成的占位符(变量),可以利用`来闭合
1
2
3MATCH (`This isn\'t a common variable`)
WHERE `This isn\'t a common variable`.name = 'A'
RETURN `This isn\'t a common variable`.happy字段别名
如果字段名需要和表达式所使用的区分,可以使用
AS <new name>
1
2MATCH (a {name: 'A'})
RETURN a.age AS SomethingTotallyDifferent可选属性
如果所指定输出的属性不存在,会返回
null
其他表达式
任何表达式都可以作为返回项
1
2MATCH (a {name: 'A'})
RETURN a.age > 30, "I'm a literal", [p=(a)-->() | p] AS `(a)-->()`唯一结果
DISTINCT
限制了相应字段的输出结果不能重复1
2MATCH (a {name: 'A'})-->(b)
RETURN DISTINCT b
WHERE
基本使用
布尔操作
可以利用逻辑连接符
AND OR XOR NOT
1
2
3
4
5
6MATCH(n:Person)
WHERE n.name = 'Peter' XOR (n.age < 30 AND n.name = 'Timothy') OR NOT (n.name = 'Timothy' OR n.name = 'Peter')
RETURN
n.name AS name,
n.age AS age
ORDER BY name过滤结点标签
在
WHERE
后写上标签谓词n:foo
, 可以过滤结点1
2
3MATCH (n)
WHERE n:Swedish
RETURN n.name, n.age过滤结点属性
同理
1
2
3MATCH (n:Person)
WHERE n.age < 30
RETURN n.name, n.age过滤关系属性
同理
1
2
3MATCH (n:Person)-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f.name, f.age, f.email过滤动态计算属性
当需要动态计算来过滤属性,使用方括号
1
2
3
4WITH 'AGE' AS propname
MATCH (n:Person)
WHERE n[toLower(propname)] < 30
RETURN n.name, n.age属性存在性检查
使用
IS NOT NULL
谓词来只包含属性存在的结点或关系1
2
3MATCH (n:Person)
WHERE n.belt IS NOT NULL
RETURN n.name, n.belt与WITH配合使用
强调当WITH写在WHERE之前时,WHERE的作用域并不会被左右
1
2
3
4MATCH (n:Person)
WITH n.name as name
WHERE n.age = 25
RETURN nameWHERE仍然视为MATCH的过滤,但WITH剩余查询部分的作用范围,也就是说,
name
是RETURN 作用域中的唯一变量
字符串匹配
字符串前缀和后缀的匹配可以使用
STARTS WITH
和ENDS WITH
. 而如果想要子串搜索,不考虑位置,用CONTAINS
. 匹配时大小写敏感,如果对非字符串使用的话将会返回NULL前缀字符串搜索利用
START WITH
位置:字符串开头
1
2
3MATCH (n:Person)
WHERE n.name STARTS WITH 'Pet'
RETURN n.name, n.age后缀字符串搜索利用
ENDS WITH
位置:字符串结尾
1
2
3MATCH (n:Person)
WHERE n.name ENDS WITH 'ter'
RETURN n.name, n.age子串搜索利用
CONTAINS
不管位置
1
2
3MATCH (n:Person)
WHERE n.name CONTAINS 'ete'
RETURN n.name, n.age反向匹配字符串
NOT
关键字排除掉所有匹配的字符串1
2
3MATCH (n:Person)
WHERE NOT n.name ENDS WITH 'y'
RETURN n.name, n.age
正规表达式
Cypher支持正轨表达式过滤。同时支持flags标志来改变字符串的匹配方式,
(?i)
大小写不敏感,(?m)
多行匹配,(?s)
支持点号。Flags标志位放在正规表达式的开头使用正规表达式进行匹配
语法:
=~ 'regexp'
1
2
3MATCH (n:Person)
WHERE n.name =~ 'Tim.*'
RETURN n.name, n.age正规表达式转义使用
转义特殊字符
. *
1
2
3MATCH (n:Person)
WHERE n.email =~ '.*\\.com'
RETURN n.name, n.age, n.email大小写不敏感
开头加
?i
1
2
3MATCH (n:Person)
WHERE n.name =~ '(?i)AND.*'
RETURN n.name, n.age
在WHERE中使用路径模式
模式过滤
模式不仅是表达式,也是谓词。模式的唯一限制是必须能够用它来表示单一路径。不能在像用MATCH中一样用逗号分隔多种路径,可以用
AND
来结合。注意这里不能引入新的变量。WHERE字段作用是排除匹配路径。
1
2
3
4
5MATCH
(timothy:Person {name:'Timothy'}),
(other:Person)
WHERE other.name IN ['Andy', 'Peter'] AND (other)-->(timothy)
RETURN other.name, other.age模式过滤使用NOT
作用就是排除路径
1
2
3
4
5MATCH
(person:Person),
(peter:Person {name: 'Peter'})
WHERE NOT (person)-->(peter)
RETURN person.name, person.age模式过滤带上属性
1
2
3MATCH (n:Person)
WHERE (n)-[:KNOWS]-({name: 'Timothy'})
RETURN n.name, n.age关系类型过滤
可以使用特殊属性
type
来比较,支持正轨表达式1
2
3MATCH (n:Person)-[r]->()
WHERE n.name='Andy' AND type(r) =~ 'K.*'
RETURN type(r), r.since
存在性子查询
遇到再看
列表
IN 操作符
检查是否有元素存在于列表中
1
2
3MATCH (a:Person)
WHERE a.name IN ['Peter', 'Timothy']
RETURN a.name, a.age错误的属性和值
当匹配一个不存在的值时,默认为false
如果想排除掉不存在的值,加上条件
1
2
3
4MATCH (n:Person)
WHERE n.belt = 'white' OR n.belt IS NULL
RETURN n.name, n.age, n.belt
ORDER BY n.name
范围
简单的范围
支持
< <= >= >
1
2
3MATCH (a:Person)
WHERE a.name >= 'Peter'
RETURN a.name, a.age复合范围
几个不等式的组合
1
2
3MATCH (a:Person)
WHERE a.name > 'Andy' AND a.name < 'Timothy'
RETURN a.name, a.age结点模式谓词
WHERE 也可以出现在结点模式里面(MATCH语句内或模式构成当中)
1
2
3WITH 30 AS minAge
MATCH (a:Person WHERE a.name = 'Andy')-[:KNOWS]->(b:Person WHERE b.age > minAge)
RETURN b.name注意 WHERE可以引用它所属于的结点的变量,但无法引用其他MATCH模式的变量
1
2MATCH (a:Persom {name: 'Andy'})
RETURN [(a)-->(b WHERE b:Person) | b.name] AS friends
CALL procedure
CALL
用于调用置于数据库中的程序
每一个程序调用都需要指定所需的参数。可以通过在程序名后用括号包裹逗号分隔的列表,或者通过可获得的查询参数作为调用参数。后者可以使用当且仅当所谓的独立程序调用时,整个查询构成了单一的CALL
语句。
大多数程序会返回由固定结果数据集组成的记录流,与Cypher查询返回的流数据类似。YIELD
子句从可获得的结果集中选择想要 返回调用程序给用户的指定变量,或者用于处理剩下的查询过程。因此,为了使用YIELD
来明确字段,输出的参数名需要预知。每一个产生的结果集都可以选择性地起别名(resultFieldName AS newName
. 所有由程序调用产生的新变量都会被添加到当前已在变量的作用域中。但是如果一个程序调用尝试重绑定已存在变量将会报错。在独立的程序调用中,YIELD *
可用于选择全部变量。这个时候输出参数的名字就并不必要。
Neo4j支持VOID的概念。VOID程序是一个不会声明和返回结果记录的程序。因此,不允许也没必要使用YIELD
.
查看一个程序的特征
当去调用一个程序时,输入参数需要知道;使用
YIELD
子句时,输出参数也需要知道。内置程序dbms.procedures
可以返回所有程序的名字,特征和描述。1
2
3CALL dbms.procedures() YIELD name, signature
WHERE name='dbms.listConfig'
RETURN signature使用引用命名空间和名字调用程序
调用内置程序
db.labels
可以列出数据库中的所有标签1
CALL `db`.`labels`
字面量参数调用程序
直接在陈述句中写出即可
1
CALL dbms.security.createUser('example_username', 'example_password', false)
使用参数来调用程序
程序参数的值与对应传递的同名参数相一致 (没有给出的就是Null)
传递参数的形式(如JSON) 取决于使用的驱动