1、Cypher(也称为CQL)是一种声明式图数据库查询语言。和SQL一样声明式语言只专注于图的表达而不关注怎么获得结果。Cypher支持事务,要么全部成功,要么全部失败。可以将多个查询放到一个事务中去提交。同时Cypher也支持唯一性,但只包括节点的唯一性,即查找“自己朋友的朋友”时,不会再查到自己;查询关系时,Cypher将尝试匹配两个方向的关系,互换开始结束节点,故关系并没有唯一性。
2、Cypher语言主要分为增删改查(CRUD)四个部分,也可抽象成读和写两个部分。但是不能同时读和写数据,每个部分要么匹配,要么更新。当需要使用聚合进行过滤时,必须使用WITH将读和写连接起来。
3、基本语法:
-
单行注释使用
//
-
关键字大小写不敏感,变量名大小写敏感
-
null意味着“一个未找到的未知值”,对待null的方式会稍有不同,具体含null值的计算需要查表
-
出现特殊字符用反引号 ` 括起来
-
字符串连接用
+
-
返回所有结果使用星号
RETURN *
4、图数据库与关系型数据库的类比
图形数据库 | 关系型数据库 |
点 | 表 |
点标签 | 表名 |
点属性 | 表字段 |
点数据(标签+属性键值对) | 表的一行数据 |
相同标签的点数据 | 表的所有数据 |
例如:
元素 | 图数据库 | 关系型数据库 |
---|---|---|
点 | (matrix) | entity |
点标签 | (matrix:Movie) | create table Movie (...) |
点属性 | {title,release,tagline} | create table Movie (id uuid pirmary key, title char,release number,tagline text); |
点数据(标签+属性键值对) | (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'}) | select * from Movie where id = 0; |
相同标签的点的所有数据 | MATCH (n:Movie) RETURN n LIMIT 25; | select * from Movie limit 25; |
5、关键字及语法
Cypher语法总体分为读和写,常用关键字如下:
-
读:MATCH, OPTIONAL MATCH, WHERE, START, 聚合, LOAD CSV
-
写:CREATE, MERGE, SET, DELETE, REMOVE, FOREACH, CREATE, UNIQUE
-
通用: RETURN, ORDER BY , LIMIT , SKIP, WITH, UNWIND, UNION , CALL
//查询
match (n) return n;
match (n:Movie) return n.title;
match (person {name:'Keanu Reeves'})--(movie) return distinct movie.title;
match (n {title: 'the matrix'}) return n;
match (:Person {name:'Keanu Reeves'})-[r]-(movie) return distinct movie.title,type(r);
//关系多选一
match (person:Person )-[r:ACTED_IN | DIRECTED]-(movie) return person,movie;
OPTIONAL MATCH
相当于SQL中的OUTER JOIN,找的和MATCH一样,找不到的项用null代替。
WHERE
在MATCH或OPTIONAL MATCH中添加约束,或与WITH一起用来过滤结果。又叫“断言”,可以出现在查询的前,中,后。
示例:用方括号动态计算属性来过滤
MATCH (n) WHERE n[toLower($prop)] < 30 RETURN n;
示例:模式过滤
MATCH (a),(b) WHERE (a)<--(b)RETURN a,b;
CASE
简单式
CASE test
WHEN value THEN result
[WHEN ...]
[ELSE <default>]
END
搜索式
CASE WHEN <predicate1> THEN result1
CASE WHEN <predicate2> THEN result2
[ELSE <default>]
END
START WITH
字符串匹配,区分大小写,类似于SQL中的LIKE %。其余还有END WITH
和 CONTAINS
IS NULL
测试一个值是否为空,相反为IS NOT NULL
START
使用遗留索引(Legacy Index)来查找,其他情况都应用MATCH
-
通过索引搜索(Index Seek)开始点。 语法:
node:<index_name>(key = "value")
或relationship:<index_name>(key = "value")
-
通过索引查询(Index Query),语法
node:<index_name>("query")
或relationship:<index_name>("query")
。(使用复杂的Lucene语法)
CREATE
用于创建点和边。使用逗号分隔。注意创建边的前提是,首先要找到边的两个节点!使用CREATE时,模式中所有不存在的部分都会被创建。
创建点
CREATE (n)
CREATE (n),(m)
CREATE (n:Person),(m:Dog)
CREATE (n:Person:Chinese)
CREATE (n:Person {name:'Gaoj', age:'18'})
创建边
//创建边
MATCH (a:Person),(b:Person) WHERE a.name = 'Gaoj' AND b.name = 'Neoob'
CREATE (a)-[r:RELATION1]->(b) RETURN a,b,r;
//创建边,有属性name,属性由 + 拼接字符串
MATCH (a:Person),(b:Person) WHERE a.name = 'Gaoj' AND b.name = 'Neoob'
CREATE (a)<-[r:RELATION2 { name: a.name + ' 我是分隔符 ' + b.name }]-(b) RETURN a,b,r;
MERGE
创建某个Patten,MERGE=MATCH + CREATE,类似于SQL中的MERGE+UPDATE,即没有则创建有则什么都不做。使用MERGE要不整个Pattern被匹配,要么整个Pattern被创建,不会应用于部分Pattern。
示例:MERGE与和MATCH+CREATE联合使用,类比SQL中的MERGE
MERGE (keanu:Person {name: 'Keanu Reeves'})
ON CREATE SET keanu.created = timestamp() //如果创建更新创建时间
ON MATCH SET keanu.lastSeen = timestamp() //如果找到更新时间,可以设置多属性,用逗号分隔
RETURN keanu.name, keanu.created, keanu.lastSeen
可以使用唯一性约束+MARGE可以防止获取冲突的结果。