
3.1 What is Cypher?
Cypher是什么?
Cypher是一种声明式图数据库查询语言,它具有丰富的表现力,能高效地查询和更新图数据。
Cypher借鉴了SQL语言的结构——查询可由各种各样的语句组合。

例如,下面是查找名为'John'和'John'朋友的朋友的查询语句。
MATCH (john {name: 'John'})-[:friend]->()-[:friend]->(fof)
RETURN john.name, fof.name
接下来在语句中添加一些过滤。给定一个用户名列表,找到名字在列表中的所有节点。匹配他们的朋友,仅返回那些他们关注的name属性以'S'开头的用户。
MATCH (user)-[:friend]->(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*'
RETURN user.name, follower.name
模式(Patterns)
Neo4j图由节点和关系构成。节点可能还有标签和属性,关系可能还有类型和属性。节点和关系都是简单的低层次的构建块。单个节点或者关系只能编码很少的信息,但模式可以将很多节点和关系编码为任意复杂的想法。
Cypher查询语言很依赖于模式。只包含一个关系的简单模式连接了一对节点。例如,一个人LIVES_IN在某个城市或者某个城市PART_OF一个国家。使用了多个关系的复杂模式能够表达任意复杂的概念,可以支持各种有趣的使用场景。例如,下面的Cypher代码将两个简单的模式连接在一起:
(:Person) -[:LIVES_IN]-> (:City) -[:PART_OF]-> (:Country)像关系数据库中的SQL一样,Cypher是一种文本的声明式查询语言。它使用ASCII 的形式来表达基于图的模式。采用类似SQL的语句,如MATCH,WHERE和DELETE,来组合这些模式以表达所预期的操作。
节点语法
Cypher采用一对圆括号()
来表示节点。如:(), (foo),使用中括号{}
表示节点的属性,不同属性可用逗号隔开。下面是一些常见的节点表示法:
()
(matrix)
(:Movie)
(matrix:Movie)
(matrix:Movie {title: "The Matrix"})
(matrix:Movie {title: "The Matrix", released: 1997})
Match (matrix:Movie {title: "The Matrix"}) return matrix
Let's use Cypher to generate a small social graph.
CREATE (ee:Person { name: "Emil", from: "Sweden", klout: 99 })CREATE
clause to create data()
parenthesis to indicate a nodeee:Person
a variable 'ee' and label 'Person' for the new nodebrackets
to add properties to the node
Now find the node representing Emil:
MATCH (ee:Person) WHERE ee.name = "Emil" RETURN ee;MATCH
clause to specify a pattern of nodes and relationships(ee:Person)
a single node pattern with label 'Person' which will assign matches to the variable 'ee'WHERE
clause to constrain the resultsee.name = "Emil"
compares name property to the value "Emil"RETURN
clause used to request particular results
CREATE
clauses can create many nodes and relationships at once.
MATCH (ee:Person) WHERE ee.name = "Emil" RETURN ee
CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }),
(ir:Person { name: "Ian", from: "England", title: "author" }),
(rvb:Person { name: "Rik", from: "Belgium", pet: "Orval" }),
(ally:Person { name: "Allison", from: "California", hobby: "surfing" }),
(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir),
(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb),
(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally),
(rvb)-[:KNOWS]->(ally)
关系语法
Cypher使用一对短横线(即--
)表示:一个无方向关系。有方向的关系在其中一段加上一个箭头(即<--
或-->
)。方括号表达式[…]
可用于添加详情。里面可以包含变量、属性和或者类型信息。关系的常见表达方式如下:
--
-->
-[role]->
-[:ACTED_IN]->
-[role:ACTED_IN]->
-[role:ACTED_IN {roles: ["Neo"]}]->
Match (n)-[role]->(m) return n, role ,m limit 10
模式语法
将节点和关系的语法组合在一起可以表达模式。
match (keanu:Person:Actor {name: "Keanu Reeves"})-[role: ACTED_IN {roles: ["Neo"]}]->(matrix:Movie {title: "The Matrix"}) return keanuFor instance, a pattern can be used to find Emil's friends:
MATCH (ee:Person)-[:KNOWS]-(friends)
WHERE ee.name = "Emil" RETURN ee, friends
MATCH
clause to describe the pattern from known Nodes to found Nodes(ee)
starts the pattern with a Person (qualified by WHERE)-[:KNOWS]-
matches "KNOWS" relationships (in either direction)(friends)
will be bound to Emil's friends
Pattern matching can be used to make recommendations. Johan is learning to surf, so he may want to find a new friend who already does:
MATCH (js:Person)-[:KNOWS]-()-[:KNOWS]-(surfer)
WHERE js.name = "Johan" AND surfer.hobby = "surfing"
RETURN DISTINCT surfer
()
empty parenthesis to ignore these nodesDISTINCT
because more than one path will match the patternsurfer
will contain Allison, a friend of a friend who surfs
使用可视化查询计划:
通过预先解释或配置文件来了解您的查询是如何工作的:
PROFILE MATCH (js:Person)-[:KNOWS]-()-[:KNOWS]-(surfer)
WHERE js.name = "Johan" AND surfer.hobby = "surfing"
RETURN DISTINCT surfer
事务
任何更新图的查询都运行在一个事务中。一个更新查询要么全部成功,要么全部失败。Cypher或者创建一个新的事务,或者运行在一个已有的事务中:
如果运行上下文中没有事务,Cypher将创建一个,一旦查询完成就提交该事务。
如果运行上下文中已有事务,查询就会运行在该事务中。直到该事务成功地提交之后,数据才会持久化到磁盘中去。
兼容性:
Cypher不是一成不变的语言。新版本引入了很多新的功能,一些旧的功能可能会被移除。如果需要,旧版本依然可以访问到。这里有两种方式在查询中选择使用哪个版本:
为所有查询设置版本:可以通过neo4j.conf中cypher.default_language_version参数来配置Neo4j数据库使用哪个版本的Cypher语言。
在查询中指定版本:简单地在查询开始的时候写上版本,如Cypher 2.3。
电影图案例(完整代码)
电影图表是一个包含演员和导演的迷你图表应用程序,这些演员和导演通过他们合作的电影有联系。
This guide will show you how to:
Create: insert movie data into the graph
Find: retrieve individual movies and actors
Query: discover related actors and directors
Solve: the Bacon Path
由于代码很长,后台回复【666】获取资料链接,或者自行到官网也可以获取。

Find操作
Find the actor named "Tom Hanks"...
MATCH (tom {name: "Tom Hanks"}) RETURN tomFind the movie with title "Cloud Atlas"...
MATCH (cloudAtlas {title: "Cloud Atlas"}) RETURN cloudAtlasFind 10 people...
MATCH (people:Person) RETURN people.name LIMIT 10Find movies released in the 1990s...
MATCH (nineties:Movie) WHERE nineties.released >= 1990 AND nineties.released < 2000 RETURN nineties.titleQuery 操作
List all Tom Hanks movies...
MATCH (tom:Person {name: "Tom Hanks"})-[:ACTED_IN]->(tomHanksMovies) RETURN tom,tomHanksMoviesWho directed "Cloud Atlas"?
MATCH (cloudAtlas {title: "Cloud Atlas"})<-[:DIRECTED]-(directors) RETURN directors.nameTom Hanks' co-actors...
MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors) RETURN coActors.nameHow people are related to "Cloud Atlas"...
MATCH (people:Person)-[relatedTo]-(:Movie {title: "Cloud Atlas"}) RETURN people.name, Type(relatedTo), relatedToSolve 操作
“六度凯文·培根”:这是一个简单的最短路径查询,称为“Bacon路径”。
Variable length patterns
Built-in shortestPath() algorithm
Movies and actors up to 4 "hops" away from Kevin Bacon
MATCH (bacon:Person {name:"Kevin Bacon"})-[*1..4]-(hollywood)
RETURN DISTINCT hollywood
Bacon path, the shortest path of any relationships to Meg Ryan
MATCH p=shortestPath(
(bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"})
)
RETURN p
Note:you only need to compare property values like this when first creating relationships.
Recommend
Extend Tom Hanks co-actors, to find co-co-actors who haven't worked with Tom Hanks...(查找没有与Tom Hanks合作过的演员z)
MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
(coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cocoActors)
WHERE NOT (tom)-[:ACTED_IN]->()<-[:ACTED_IN]-(cocoActors) AND tom <> cocoActors
RETURN cocoActors.name AS Recommended, count(*) AS Strength ORDER BY Strength DESC
Find someone to introduce Tom Hanks to Tom Cruise
MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
(coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cruise:Person {name:"Tom Cruise"})
RETURN tom, m, coActors, m2, cruise
Clean up
When you're done experimenting, you can remove the movie data set.
Note:
Nodes can't be deleted if relationships exist
Delete both nodes and relationships together
WARNING: This will remove all Person and Movie nodes!
Delete all Movie and Person nodes, and their relationships
MATCH (n) DETACH DELETE n
Note you only need to compare property values like this when first creating relationships
Prove that the Movie Graph is gone
MATCH (n) RETURN n3.2Cypher基本语法
3.2.1类型
Cypher处理的所有值都有一个特定的类型,它支持如下类型:
数值型
字符串
布尔型
节点
关系
路径
映射(Map)
列表(List)
3.2.2表达式
Cypher中的表达式如下:
十进制(整型和双精度型)的字面值:13, -4000, 3.14, 6.022E23
十六进制整型字面值(以0x开头):0x13zf, 0xFC3A9, -0x66eff
八进制整型字面值(以0开头):01372, 02127, -05671
字符串字面值:'Hello', "World"
布尔字面值:true, false, TRUE, FALSE
变量:n, x, rel, myFancyVariable,
A name with weird stuff in it[]!属性:n.prop, x.prop, rel.thisProperty, myFancyVariable.
(weird property name)动态属性:n["prop"], rel[n.city + n.zip], map[coll[0]]
参数:
$param, $0表达式列表:['a', 'b'], [1, 2, 3], ['a', 2, n.property, $param], [ ]
函数调用:length(p), nodes(p)
聚合函数:avg(x.prop), count(*)
路径-模式:(a)-->()<--(b)
计算式:1 + 2 >3 and 3 < 4.
返回true或者false的断言表达式:a.prop = 'Hello', length(p) >10, exists(a.name)
正则表达式:a.name =~ 'Tob.*'
大小写敏感的字符串匹配表达式:a.surname STARTS WITH 'Sven', a.surname ENDS WITH 'son' or a.surname CONTAINS 'son'
CASE表达式
3.2.3转移字符
Cypher中的字符串可以包含如下转义字符:
| 字符 | 含义 |
|---|---|
| \t | 制表符 |
| \b | 退格 |
| \n | 换行 |
| \r | 回车 |
| \f | 换页 |
| ' | 单引号 |
| " | 双引号 |
| \ | 反斜杠 |
| \uxxxx | Unicode UTF-16编码点(4位的十六进制数字必须跟在\u后面) |
| \Uxxxxxxxx | Unicode UTF-32 编码点(8位的十六进制数字必须跟在\U后面) |
3.2.4Case表达式
计算表达式的值,然后依次与WHEN语句中的表达式进行比较,直到匹配上为止。如果未匹配上,则ELSE中的表达式将作为结果。如果ELSE语句不存在,那么将返回null。
语法:
CASE test
WHEN value THEN result
[WHEN ...]
[ELSE default]
END参数
test:一个有效的表达式
value:一个表达式,它的结果将与test表达式的结果进行比较
result:如果value表达式能够与test表达式匹配,它将作为结果表达式
default:没有匹配的情况下的默认返回表达式
查询
MATCH (n)
RETURN
CASE n.eyes
WHEN 'blue'
THEN 1
WHEN 'brown'
THEN 2
ELSE 3 END AS result
一般的Case表达式
CASE
WHEN predicate THEN result
[WHEN ...]
[ELSE default]
END
参数:
predicate:判断的断言,以找到一个有效的可选项
result:如果predicate匹配到,result就作为结果表达式
default:没有匹配到的情况下,默认返回表达式
MATCH (n)
RETURN
CASE
WHEN n.eyes='blue'
THEN 1
WHEN n.age<30
THEN 2
ELSE 3 END AS result
3.2.5变量
当需要引用模式(pattern)或者查询的某一部分的时候,可以对其进行命名。针对不同部分的这些命名被称为变量。变量是区分大小写的。例如:
MATCH (n)-[r]->(b) RETURN b 这里的n和b和r就是变量。
3.2.6参数
Cypher支持带参数的查询。这意味着开发人员不是必须用字符串来构建查询。此外,这也让执行计划的缓存更容易。
参数能够用于WHERE语句中的字面值和表达式,START语句中的索引值,索引查询以及节点和关系的id。参数不能用于属性名、关系类型和标签,因为这些模式(pattern)将作为查询结构的一部分被编译进查询计划。
合法的参数名是字母,数字以及两者的组合。下面是一个使用参数的完整例子。参数以JSON格式提供。具体如何提交它们取决于所使用驱动程序。
字符串
参数
{
"name" : "Johan"
}
Match (n) where n.name=$name return n
3.2.7运算符
数学运算符 :包括+,-,*,/ 和%,^。
比较运算符 :包括=,<>,<,>,<=,>=,IS NULL和IS NOT NULL。
布尔运算符 :包括AND,OR,XOR和NOT。
字符串运算符 :连接字符串的运算符为+。正则表达式的匹配运算符为
=~
。列表运算符 :列表的连接也可以通过+运算符。可以用
IN
来检查列表中是否存在某个元素。值的相等与比较 :Cypher支持使用=和<>来比较两个值的相等/不相等关系。同类型的值只有它们是同一个值的时候才相等,如3 = 3和"x" <> "xy"。
值的排序与比较:比较运算符<=,<(升序)和>=,>(降序)可以用于值排序的比较。如下所示:
数字型值的排序比较采用数字顺序
java.lang.Double.NaN大于所有值
字符串排序的比较采用字典顺序。如"x" < "xy"
布尔值的排序遵循false < true
当有个参数为null的时候,比较结果为null。如null < 3的结果为null
将其他类型的值相互比较进行排序将报错
链式比较运算:比较运算可以被任意地链在一起。如x < y <= z等价于x < y AND y <= z。如:
MATCH (n) WHERE 21 < n.age <= 30 RETURN n
//等价于
MATCH (n) WHERE 21 < n.age AND n.age <= 30 RETURN n
3.2.8注释
Cypher语言的注释类似其他语言,用双斜线//来注释行。例如:
MATCH (n) RETURN n //这是行末尾注释
MATCH (n)
//这是整行注释
RETURN n
MATCH (n) WHERE n.property = '//这不是注释' RETURN n
3.2.9模式(Patterns)
使用模式可以描述你期望看到的数据的形状。例如,在MATCH、CREATE、DELETE等语句中,当用模式描述一个形状的时候,Cypher将按照模式来获取相应的数据。模式描述数据的形式很类似在白板上画出图的形状。通常用圆圈来表达节点,使用箭头来表达关系。
节点模式
模式能表达的最简单的形状就是节点。节点使用一对圆括号表示,然后中间含一个名字。例如:
(a)
。这个模式描述了一个节点,其名称使用变量a表示。关联节点的模式
模式可以描述多个节点及其之间的关系。Cypher使用箭头来表达两个节点之间的关系。例如:
(a)-->(b)
(a)-->(b)<--(c)
//节点的命名仅仅当后续的模式或者Cypher查询中需要引用时才需要。如果不需要,则命名可以省略。如:
(a)-->()<--(c)标签
模式除了可以描述节点之外,还可以用来描述标签。比如:
(a:User)-->(b)
//也可以描述一个节点的多个标签,如:
(a:User:Admin)-->(b)指定属性
属性在模式中使用键值对的映射结构来表达,然后用大括号包起来。例如,一个有两个属性的节点如下所示:
(a {name: 'Andres', sport: 'Brazilian Ju-Jitsu'})
//关系中的属性:
(a)-[{blocked: false}]->(b)当模式中有属性时,它实际上为数据增加了额外的约束。在CREATE中,属性会被增加到新创建的节点和关系中。在MERGE语句中,属性将作为一个约束去匹配数据库中数据是否存在该属性。如果没有匹配到,MERGE和CREATE的行为一样,属性会被增加到新创建的节点和关系中。
描述关系
如前面的所做例子所示,可以用箭头简单地描述两个节点之间的关系。它描述了关系的存在性和方向性。但如果不关心关系的方向,则箭头的头部可以省略。例如:
(a)--(b)与节点类似,如果后续需要引用到该关系,则可以给关系赋一个变量名。变量名需要用方括号括起来,放在箭头的短横线中间,如下所示:
(a)-[r]->(b)就像节点有标签一样,关系可以有类型(type)。给关系指定类型,如下所示:
(a)-[r:REL_TYPE]->(b)不像节点可以有多个标签,关系只能有一个类型。但如果所描述的关系可以是一个类型集中的任意一种类型,可以将这些类型都列入到模式中,它们之间以竖线“|”分割。如:
(a)-[r:TYPE1|TYPE2]->(b)注意:这种模式仅适用于描述已经存在的数据(如在MATCH语句中),而在CREATE或者MERGE语句中是不允许的,因为一个关系不能创建多个类型。
与节点类似,关系的命名也是可以省略的。如:
(a)-[:REL_TYPE]->(b)与使用一串节点和关系来描述一个长路径的模式不同,很多关系(以及中间的节点)可以采用指定关系的长度的模式来描述。例如:
(a)-[*2]->(b)它描述了一张三个节点和两个关系的图。这些节点和关系都在同一条路径中(路径的长度为2)。它等同于:
(a)-->()-->(b)关系的长度也可以指定一个范围,这被称为可变长度的关系。例如:
(a)-[*3..5]->(b)关系的长度最小值为3,最大值为5。它描述了一个或者有4个节点和3个关系,或者5个节点4个关系,或者6个节点和5个关系连在一起的图组成的一条路径。
长度的边界也是可以省略的,如描述一个路径长度大于等于3的路径:
(a)-[*3..]->(b)
路径长度小于等于5的路径,如:(a)-[*..5]->(b)两个边界都可以省略,这允许任意长度的路径,如:
(a)-[*]->(b)match (me)-[:KNOWS*1..2]-(remore_friend)
where me.name ='Filipa'
return remote_friend.name列表Cypher对列表(list)有很好的支持。可以使用方括号和一组以逗号分割的元素来创建一个列表。例如:
RETURN [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] AS listreturn range(0,10)
:制定了列表包含元素的开始数字和结束数字,两端也是被包含在内。空值
空值null在Cypher中表示未找到或者未定义。从概念上讲,null意味着”一个未找到的未知值”。对待null会与其他值有些不同。例如从节点中获取一个并不存在的属性将返回null。大多数以null作为输入的表达式将返回null。这包括WHERE语句中用于断言的布尔表达式。
null不等于null。两个未知的值并不意味着它们是同一个值。因此,null = null返回null而不是true。判断 某个节点上 有或没有 某个属性,如下:
Match (n) where n.name is null return n
Match (n) where n. name is not null return n空值的逻辑运算
逻辑运算符(包括AND,OR,XOR,IN,NOT)把null当作未知的三值逻辑值。下面为AND,OR和XOR的逻辑值表。
a b a AND b a OR b a XOR b false false false false false false null false null null false true false true true true false false true true true null null true null true true true true false null false false null null null null null null null null true null true null 空值与IN
IN运算符遵循类似的逻辑。如果列表中存在某个值,结果就返回true。如果列表包含null值并且没有匹配到值,结果返回null。否则结果为false。下面表中是一些例子:
表达式 结果 2 IN [1, 2, 3] true 2 IN [1, null, 3] null 2 IN [1, 2, null] true 2 IN [1] false 2 IN [] false null IN [1, 2, 3] null null IN [1, null, 3] null null IN [] false all, any, none和single与IN类似,如果可以确切地计算结果,将返回true或者false。否则将返回null。
返回空值的表达式
从列表中获取不存在的元素:
[][0]
,head([])试图访问节点或者关系的不存在的属性:n.missingProperty
与null做比较:1 < null
包含null的算术运算:1 + null
包含任何null参数的函数调用:sin(null)
- END -
学习图形数据库Neo4j也是因为公司项目开发需要,而且也是刚开始学习,自己也找了些学习资料,如果有小可爱需要,添【lxcecho】联系我获取,一块学习交流探讨。
最后,请素质三连,点赞、在看、转发,关注并标星公众号 Just For Joy 获取最新内容,后台回复 666 获取学习近期学习笔记,更多内容陆续奉上。





