目录
Cypher简介
Cypher查询子句(Clauses)
MATCH
OPTIONAL MATCH
RETURN
WITH
UNWIND
WHERE
ORDER BY
SKIP
LIMIT
CREATE
DELETE
SET
REMOVE
FOREACH
MERGE
CALL[…YIELD]
UNION
LOAD CSV
Cypher是一种声明性的图形查询语言,允许对图形进行表达性和高效的查询和更新。它的设计适合于开发人员和操作专业人员。Cypher设计简单,但功能强大;高度复杂的数据库查询可以很容易地表达出来,使您能够专注于自己的领域,而不是在数据库访问中迷失方向。
Cypher语句作为图数据库Neo4j的查询语言,在Neo4j学习使用中尤为重要。高效简单的语法即使刚刚接触也可以快速上手并且查询出自己想要的结果。
如果有SQL的基础基本上学习的成本很低,结构与SQL相似都有子查询连查询的关键词都有许多相同的。
下面放出个例子:
MATCH (john {name: 'John'})-[:FRIEND]->()-[:FRIEND]->(fof)
RETURN john.name, fof.name
其中有两个关键词,MATCH和RETURN。大概意思就是根据MATCH的条件,返回RETURN后面的内容。
所以示例的意思就是找到John的朋友的朋友,返回John的名字和朋友的朋友的名字。
一个复杂的事情轻而易举的就表达了出来,可以看到既没有使用表关联也不用先找到John的朋友是谁。
下面我们就先看看Cypher中的查询子句都有什么。
指定要在数据库中搜索的模式。
这是最最最最常用的一个关键字。使用范围非常广泛。可以搜索节点(node)、关系(relationship)以及更高级的更复杂的深层关系和最短路径。
下面是MATCH用法示例:
MATCH (n)
RETURN n
-- 找到全部节点
-- 返回全部
MATCH (:Person { name: 'Oliver Stone' })-->(movie)
RETURN movie.title
-- 找到与'Oliver Stone'有关系的movie
-- 返回movie的title
MATCH (charlie { name: 'Charlie Sheen' })-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)
RETURN movie.title, director.name
-- 找到'Charlie Sheen'有:ACTED_IN关系的movie,并且找到movie有:DIRECTED关系的director
-- 返回movie的title和director的name
OPTIONAL MATCH与MATCH的区别就是OPTIONAL MATCH可以返回null值。
MATCH (a:Movie { title: 'Wall Street' })
OPTIONAL MATCH (a)-[r:ACTS_IN]->()
RETURN a.title, r
--结果
a.title r
"Wall Street"
在查询的返回部分,你可以定义返回的是节点、关系或属性。
其中有几种特殊用法:
RETURN *
-- 返回全部元素
RETURN DISTINCT b
-- 使用distinct关键词去重结果
RETURN a.age AS SomethingTotallyDifferent
-- 使用AS关键词设置别名
使用WITH,可以在查询部分之前,将输出结果传递并对其进行操作。操作可以是结果集中的形状或条目数。
简单的说就是传递第一步算出的结果,进一步操作之后再返回结果。
其中常用的操作有:
MATCH (david { name: 'David' })--(otherPerson)-->()
WITH otherPerson, count(*) AS foaf
WHERE foaf > 1
RETURN otherPerson.name
-- 使用where条件过滤结果
MATCH (n)
WITH n
ORDER BY n.name DESC LIMIT 3
RETURN collect(n.name)
-- 使用order by对结果排序
使用unwind,可以将任何列表转换回单独的行。这些列表可以是传入的参数。
来一个示例就清楚了
UNWIND [1, 2, 3, NULL ] AS x
RETURN x, 'val' AS y
--X为数组,y为字符常量
结果如下
x | y |
---|---|
|
|
|
|
|
|
|
|
unwind与collect是相互转换的关系
WITH [1, 1, 2, 2] AS coll
UNWIND coll AS x
WITH DISTINCT x
RETURN collect(x) AS setOfVals
-- 先用unwind转为行然后去重,最后返回的时候用collect再转换回数组
结果:
[1,2]
在使用WITH和START的情况下,其中WHERE只是过滤结果。
在使用MATCH和 OPTIONAL MATCH的情况下,其中WHERE还可以为语句加入约束条件。
总之就是用法和在sql中一样,然后可以用在以上的关键词的时候。
简单的应用
MATCH (n)
WHERE n:Swedish
RETURN n.name, n.age
-- 对节点的标签筛选
MATCH (n)
WHERE n.age < 30
RETURN n.name, n.age
-- 对节点的属性筛选
MATCH (n)
WHERE exists(n.belt)
RETURN n.name, n.belt
-- 找到存在某个属性的节点
字符串的匹配:
MATCH (n)
WHERE n.name STARTS WITH 'Pet'
RETURN n.name, n.age
-- 找到"Pet"开头的name
MATCH (n)
WHERE n.name ENDS WITH 'ter'
RETURN n.name, n.age
-- 找到"ter"结尾的name
MATCH (n)
WHERE n.name CONTAINS 'ete'
RETURN n.name, n.age
-- 找到包含"ete"的name
与SQL类似也是排序的关键词,请注意,不能对节点或关系进行排序,只能对这些节点或关系的属性进行排序。
简单的例子:
MATCH (n)
RETURN n.name, n.age
ORDER BY n.age, n.name
-- 最后结果按n.age, n.name排序,默认顺序
MATCH (n)
RETURN n.name, n.age
ORDER BY n.name DESC
-- 最后结果按n.name排倒序
结果集将从顶部修剪。请注意,查询一定要有order BY子句,否则不会保证结果的顺序。
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 3
-- 结果跳过前三条
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP 1
LIMIT 2
-- 结果跳过第一条之后取两条
LIMIT接受计算结果为正整数的任何表达式 — 但是,表达式不能引用节点或关系。
简单来说就是取结果的前几条。
示例:
MATCH (n)
RETURN n.name
ORDER BY n.name
LIMIT 3
-- 只取结果的前三条
CREATE子句用于创建节点和关系。
CREATE (n:Person)
-- 创建一个带标签的节点
MATCH (a:Person),(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE]->(b)
RETURN type(r)
-- 创建a节点和b节点的关系
CREATE p =(andy { name:'Andy' })-[:WORKS_AT]->(neo)<-[:WORKS_AT]-(michael { name: 'Michael' })
RETURN p
-- 同时创建节点、属性和关系,一条全路径
DELETE子句用于删除节点、关系或路径。
有关删除属性和标签的信息,要使用REMOVE。
请记住,如果不同时删除节点上开始或结束的关系,则无法删除节点。可以明确的删除关系。
也可以使用DETACH delete同时删除。
MATCH (n:Person { name: 'UNKNOWN' })
DELETE n
-- 删除单个没有关系的节点
MATCH (n)
DETACH DELETE n
-- 删除全部的节点和关系
MATCH (n:Person { name: 'UNKNOWN' })
DELETE n
-- 删除这个节点相关的关系
SET子句用于更新节点上的标签以及节点和关系上的属性。
MATCH (n { name: 'Andy' })
SET n.surname = 'Taylor'
RETURN n.name, n.surname
--给节点上加上属性surname
MATCH (p { name: 'Peter' })
SET p = { }
RETURN p.name, p.age
-- 把节点的所有属性更新为null,用于删除全部属性
MATCH (p { name: 'Peter' })
SET p += { age: 38, hungry: TRUE , position: 'Entrepreneur' }
RETURN p.name, p.age, p.hungry, p.position
-- 使用+=号更新多个属性,可以把原有属性,新建没有的属性,而且不会把null赋值
REMOVE子句用于从节点和关系中删除属性,并从节点中删除标签。
如果要删除节点和关系需要用DELETE
MATCH (a { name: 'Andy' })
REMOVE a.age
RETURN a.name, a.age
--删除a节点的age属性
FOREACH可以用于更新数据,例如对路径中的元素或聚合创建的列表执行更新命令。
MATCH p =(begin)-[*]->(END )
WHERE begin.name = 'A' AND END .name = 'D'
FOREACH (n IN nodes(p)| SET n.marked = TRUE )
--按照begin到END的方向,把所有节点的属性marked 都设置为TRUE
MERGE要么匹配现有节点并将其绑定,要么创建新数据并将其绑定。这就像匹配和创建的组合。另外如果匹配或者新建后还可以指定别的操作。
我觉得是至关重要的一个子句。简单的说就是如果存在就合并如果不存在就新建。
MERGE (robert:Critic)
RETURN robert, labels(robert)
--合并节点和属性
MERGE (person:Person)
ON MATCH SET person.found = TRUE RETURN person.name, person.found
--合并节点,然后在合并节点上面设置一个新的属性
调用现成的过程函数使用CALL,有不同的函数库,也可以后期加载如APOC这样的高级函数库。
现在先简单介绍一下:
CALL `db`.`labels`
-- 返回数据库内所有的labels
UNION将两个或多个查询的结果合并到一个结果集中,该结果集包含属于UNION中所有查询的所有行。
用法和作用与SQL一致
MATCH (n:Actor)
RETURN n.name AS name
UNION
MATCH (n:Movie)
RETURN n.title AS name
用于导入CSV文件格式的数据,是自带的大批量数据导入的方式。日后再详细甄别每种数据导入的优劣。
下面最简单的导入方式可以解决大多数问题。
LOAD CSV FROM '{csv-dir}/artists.csv' AS line
CREATE (:Artist { name: line[1], year: toInteger(line[2])})
--导入本地的CSV文件
LOAD CSV FROM 'http://data.neo4j.com/bands/artists.csv' AS line
CREATE (:Artist { name: line[1], year: toInteger(line[2])})
--导入远程的CSV文件