Cypher常用的语句如下:
match: 匹配图模式,这是从图中获取数据的常见方法
() 用括号表示节点
-->和<-- 用一对横杠和大于号、小于号来表示联系
<和> 符号标明了联系的方向
-[:knows]- 在两个横杠中间,我们把联系的名字放在一对方括号里,前面加上一个冒号
where: 不是独立语句,而是与match,optinal match 和 with的一部分,用于给模式添加约束或者过滤传递给with的中间结果(提供过滤模式匹配结果的条件)
create和create unique: 用来创建节点和联系
merge: 匹配已经存在的或者创建新节点和模式,这对于有唯一性约束的时候非常有用
delete: 删除节点、联系以及属性
set(和 remove): 用来设置属性值和给节点添加标签,使用remove移除他们
foreach: 对一个列表中的每个元素执行更新操作
union: 合并两个或更多查询结果
with: 链式查询,前一个查询的结果作为后一个查询的条件,和linux的管道命令很相似
start: 在图中指定一个或多个起始点,它可以是节点,也可以是联系(已经不推荐使用start,现在推荐使用match)
return: 定义返回的结果
1.准备基础数据
用户信息com_user
CREATE (John:com_user {name:'John'})
CREATE (Jon:com_user {name:'Jon'})
CREATE (Steve:com_user {name:'Steve'})
CREATE (Sara:com_user {name:'Sara'})
CREATE (Maria:com_user {name:'Maria'})
CREATE (John)-[:friend]->(Jon),
(John)-[:friend]->(Sara),
(Jon)-[:friend]->(Steve),
(Sara)-[:friend]->(Maria)
2.基本操作
查找名称为'John'和'John'朋友的朋友的查询语句
match (a {name:'John'})-[:friend]->(b)-[:friend]->(c)
return a.name,c.name
给定一个用户列表,找到名字在列表中的所有节点,匹配他们的朋友,仅返回哪些他们关注的name属性以‘S’开头的用户
match (a)-[:friend]->(b)
where a.name in ['Jon','John','Sara','Maria','Steve'] and b.name =~ 'S.*'
return a.name,b.name
3.模式(Patterns)
Neo4j图由节点和关系构成,节点可能还有标签和属性,关系可能还有类型和属性,节点表达的是实体,关系连接一对节点。节点可以看做类似关系数据库中的表,但又不完全一样,节点的标签可以理解为不同的表名,属性类似于关系数据库中的列,一个节点的数据类似关系数据库中表的一行数据。拥有相同标签的节点通常
具有类似的属性,但不必完全一样,这点与关系数据库中一张表的行数据拥有相同的列是不一样的。
使用聚合数据进行过滤
match (n {name:'John'})-[:friend]-(friend)
with n,count(friend) as friendsCount
where friendsCount > 3
return n,friendsCount
将聚合数据更新到图中
match (n {name:'John'})-[:friend]-(friend)
with n,count(friend) as friendsCount
set n.friendsCount = friendsCount
return n.friendsCount
事物
可以将多个查询作为单个事物来提交
(1).开始一个事物
(2).运行多个Cypher更新查询
(3).一次提交这些查询
唯一性
查询一个用户的朋友的朋友不应该返回该用户
创建节点和关系
create (adam:User {name:'Adam'}), (pernilla:User {name:'Pernilla'}), (david:User {name:'David'}),
(adam)-[:friend]->(pernilla), (pernilla)-[:friend]->(david)
下面查询Adam的朋友的朋友
match (user:User {name:'Adam'})-[r1:friend]-()-[r2:friend]-(friend_of_a_friend)
return friend_of_a_friend.name as fofName
4.语句
语句可以分为三类,包括读语句、写语句和通用语句
读语句:match、optional match、where、start、aggregation和load csv
写语句:create、merge、set、delete、remove、foreach和create unique
通用语句:return、order by、limit、skip、with、unwind、union和call
准备基础数据:
create (a:Person {name:'Charlie Sheen'})
create (b:Person {name:'Martin Sheen'})
create (c:Person {name:'Michael Douglas'})
create (d:Person {name:'Oliver Stone'})
create (e:Person {name:'Rob Reiner'})
create (f:Movie {title:'Wall Street'})
create (g:Movie {title:'The American President'})
create (d)-[:directed]->(f),
(e)-[:directed]->(g),
(c)-[:acted_in {roles:['Gordon Gekko']}]->(f),
(a)-[:acted_in {roles:['Bud Fox']}]->(f),
(b)-[:acted_in {roles:['Carl Fox']}]->(f),
(c)-[:acted_in {roles:['President Andrew Shepherd']}]->(g),
(b)-[:acted_in {roles:['A.J.MacInerney']}]->(g)
查询所有节点
返回数据库中所有的电影
match (movie:Movie) return movie.title
返回Oliver Stone导演的所有电影
符号--意为相关的,这个关系不带有类型和方向
match (director {name:'Oliver Stone'})--(movie)
return movie.title
匹配标签,返回与Person 'Oliver Stone'相连的带有Movie标签的所有节点
match (director {name:'Oliver Stone'})--(movie:Movie)
return movie.title
查找关系
外向关系
关系的方向通过-->或者<--来表示
返回与Person 'Oliver Stone'外向连接的所有节点
match (:Person {name:'Oliver Stone'})-->(movie)
return movie.title
返回 'Oliver Stone'的外向关系的类型
match (:Person {name:'Oliver Stone'})-[r]->(movie)
return type(r)
匹配关系类型
当已知要匹配关系的类型时,可以通过冒号后面紧跟关系类型
返回'Wall Street'中的所有演员
match (wallstreet:Movie {title:'Wall Street'})<-[:acted_in]-(actor)
return actor.name
匹配多种关系类型
当需要匹配多种关系类型中的一种时,可以通过竖线(|)将多个关系连接在一起
返回与 'Wall Street'节点关系为acted_in或者directed的所有节点
match (wallstreet:Movie {title:'Wall Street'})<-[:acted_in|:directed]-(person)
return person.name
匹配关系类型和使用关系变量
如果想通过变量来引用关系和指定关系类型,可以将他们放在一起
返回'Wall Street'中所有演员的角色
match (wallstreet:Movie {title:'Wall Street'})<-[r:acted_in]-(person)
return r.roles
关系深度
带有特殊字符的关系类型
某些时候数据库中可能会有非字母字符的类型,或者中间含有空格,可以使用反引号将他们括起来
返回带有空格的关系类型
match (e:Person {name:'Rob Reiner'})-[r:`type with space`]->()
return type(r)
多个关系
关系可以多语句以()--()的形式来表达,或者他们相互连接在一起
返回'Charlie Sheen'演的电影和该电影的导演
match (a:Person {name:'Charlie Sheen'})-[:acted_in]->(movie)<-[:directed]-(director)
return movie.title,director.name
可变长关系
可变长关系和节点的语法如下:
-[:type*minHops..maxHops]->
minHops和maxHops都是可选的,默认值分别为1和无穷大,当没有边界值的时候,点也可以省略。当只设置了一个边界的时候,如果点省略了就意味着是一个固定长度的模式
返回与'Charlie Sheen'关系为1跳(Hop)到3跳的所有电影
match (a:Person {name:'Charlie Sheen'})-[:acted_in*1..3]-(movie:Movie)
return movie.title
变长关系的关系变量
当连接两个节点之间的长度是变长时,那么关系变量返回的将可能是一个关系列表
返回一个关系列表
match (a:Person {name:'Charlie Sheen'})-[r:acted_in*2]-(co_actor)
return r
变长路径上的属性
带有属性的可变长度关系意味着路径上的所有关系都必须包含给定的属性值。在这个查询中,'Charlie Sheen'和'Martin Sheen'之间有两条路径。
其中一条包含一个'blocked'关系,另外一条则没有,首先通过以下语句增加blocked和unblocked
返回Charlie Sheen'和'Martin Sheen'之间满足blocked属性值为false的所有关系
match p=(charlie:Person)-[* {blocked:false}]-(martin:Person)
where charlie.name='Charlie Sheen' and martin.name='Martin Sheen'
return p
零长度路径
如果变长路径的下界值为零,则意味着两个变量指向同一个节点
返回电影本身及一级跳关系的演员和导演
match (f:Movie {title:'Wall Street'})-[*0..1]-(x)
return x
命名路径
如果想返回或者需要对路径进行过滤,可以将路径赋值给一个变量
返回从开始'Michael Douglas'的两条路径
match p=(michael {name:'Michael Douglas'})-->()
return p
匹配一簇关系
当模式包含一簇关系时,关系模式不会指定方向,Cypher尝试匹配两个方向的关系
返回两个相连的节点,一个为开始节点,一个为结束节点
match (a)-[r]-(b)
where id(r)=26
return a,b
最短路径
单条最短路径
可以通过shortestPath函数很容易找到两个节点之间的最短路径
match (a:Person {name:'Charlie Sheen'}), (d:Person {name:'Oliver Stone'}), p=shortestPath((a)-[*..15]-(d))
return p
带断言的最短路径
最短路径模式中where语句的断言通常在检索匹配的最短路径之前就进行处理了
寻找'Charlie Sheen'和'Martin Sheen'之间的最短路径,where断言确保不考虑两个节点之间的 父亲/儿子关系
match (a:Person {name:'Charlie Sheen'}), (b:Person {name:'Martin Sheen'}), p=shortestPath((a)-[*]-(b))
where none (r in rels(p) where type(r)='father')
return p
所有的最短路径
找到两个节点之间的所有的最短路径
找到'Martin Sheen'和'Michael Douglas'之间的两条最短路径
match (a:Person {name:'Martin Sheen'}), (b:Person {name:'Michael Douglas'}), p=shortestPath((a)-[*]-(b))
return p
通过id查找节点或关系
通过id查询节点
可以在断言中使用id()函数来根据id查询节点
注意:neo4j会重用已删除的节点和关系的内部id,这意味着依赖neo4j内部id存在风险,因此建议通过程序来产生id
match (n) where id(n)=0 return n
通过id查询关系
通过id查找关系与节点类似,但这在实践中不推荐这么做
match ()-[r]->() where id(r)=0 return r
通过id查询多个节点
match (n) where id(n) in [0,3,5]