Cypher图数据库查询语言(1) :Cypher概述
Cypher图数据库查询语言(2) :Cypher基本语法
Cypher图数据库查询语言(3) :Cypher语句-MATCH,OPTIONAL MATCH
Cypher图数据库查询语言(4) :Cypher语句-WHERE
Cypher图数据库查询语言(5) :Cypher语句-START,Aggregation 和 LOAD CSV
Cypher图数据库查询语言(6) :Cypher语句-CREATE,MERGR
Cypher图数据库查询语言(7) :Cypher语句-SET,DELETE,REMOVE
Cypher图数据库查询语言(8) :Cypher语句-FOREACH,CREATE UNIQUE
Cypher图数据库查询语言(9) :Cypher语句-RETURN,ORDER BY
Cypher图数据库查询语言(10) :Cypher语句-LIMIT,SKIP
Cypher图数据库查询语言(11) :Cypher语句-WITH,UNWIND,UNION,CALL
语句可分为三类,包括读语句、写语句和通用语句。
- 读语句:MATCH、OPTIONAL MATCH、WHERE、START、Aggregation和LOAD CSV。
- 写语句:CREATE、MERGR、SET、DELETE、REMOVE、FOREACH和CREATE UNIQUE。
- 通用语句:RETURN、ORDER BY、LIMIT、SKIP、WITH、UNWIND、UNION和CALL。
3 WHERE
WHERE在MATCH或OPTIONAL MATCH语句中添加约束,或者与WITH一起使用来过滤结果。
WHERE不能单独使用,它只能作为MATCH、OPTIONAL MATCH、START、WITH的一部分。如果是在START和WITH中,它用于过滤结果。对于MATCH和OPTIONAL MATCH,WHERE为模式增加约束,它不能看作是匹配完成后的结果过滤。
3.1 基本使用
3.1.1 布尔运算
可以在WHERE中使用布尔运算符,如AND、OR,以及布尔函数NOT。
MATCH (n)
WHERE n.name = 'Peter' XOR (n.age < 30 AND n.name = 'Tobias') OR NOT (n.name = 'Tobias' OR n.name = 'Peter')
RETURN n
3.1.2 节点标签的过滤
可以在WHERE中类似使用WHERE n:foo 写入标签断言来过滤节点。
MATCH (n)
WHERE n:Swedish
RETURN n
结果: 将返回"Andres"节点。
如果要查询不包含某个标签的其他所有节点的反向查询,可在WHERE后加NOT。
3.1.3 节点属性的过滤
可以在WHERE语句中对节点的属性进行过滤。
MATCH (n)
WHERE n.age < 30
RETURN n
结果: 返回了'Tobias'节点,因为他的年龄小于30。
3.1.4 关系属性的过滤
要对关系属性进行过滤,可在WHERE中添加如下关键词:
MATCH (n)-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f
结果: 返回了'Peter',因为Andres自1999年就认识他了。
3.1.5 动态节点属性过滤
以方括号语法的形式可使用动态计算的值来过滤属性。
参数:
{
"prop" : "AGE"
}
查询:
MATCH (n)
WHERE n[toLower($prop)] < 30
RETURN n
结果: 返回了'Tobias',因为他的年龄小于30.
3.1.6 属性存在性检查
使用exists()只能检查节点或者关系的某个属性是否存在。
MATCH (n)
WHERE exists(n.belt)
RETURN n
结果: 'Andres'被返回了,因为只有他有belt属性。
3.2 字符串匹配
可以用 STARTS WITH 和 ENDS WITH 来匹配字符串的开始和结尾。如果不关心所匹配字符串的位置,可以用 CONTAINS ,匹配是区分大小写的。
3.2.1 匹配字符串的开始
STARTS WITH 用于以大小写敏感的方式匹配字符串的开始。
MATCH(n)
WHERE n.name STARTS WITH 'Pet'
RETURN n
结果: 'Peter'返回了,因为他的名字以'Pet'开始。
3.2.2 匹配字符串的结尾
ENDS WITH 用于以大小写敏感的方式匹配字符串的结尾。
MATCH(n)
WHERE n.name ENDS WITH 'ter'
RETURN n
结果: 'Peter'返回了,因为他的名字以'ter'结尾。
3.2.3 字符串包含
CONTAINS 用于检查字符串中是否包含某个字符串,它是大小写敏感的,且不关心匹配部分在字符串中的位置。
MATCH(n)
WHERE n.name CONTAINS 'ete'
RETURN n
结果: 'Peter'返回了,因为他的名字包含'ete'字符串。
3.2.4 字符串反向匹配
使用NOT关键词可以返回不满足给定字符串匹配要求的结果。
MATCH(n)
WHERE NOT n.name ENDS WITH 's'
RETURN n
结果: 'Peter'返回了,因为他的名字不以's'结尾。
3.3 正则表达式
Cypher支持正则表达式过滤。正则表达式的语法继承来自Java正则表达式。它支持字符串如何匹配标记,包括不区分大小写(?i),多行(?m) 和单行(?s)。标记放在正则表达式的开头,例如MATCH(n) WHERE n.name =~ '(?i)Lon.*' RETURN n 将返回名字为"London'和'LonDoN'的节点。
3.3.1 正则表达式
可以使用 =~'regexp'来进行正则表达式的匹配。
MATCH (n)
WHERE n.name =~ 'Tob.*'
RETURN n
结果: 'Tobias'返回了,因为他的名字以'Tob'开始。
3.3.2 正则表达式中的转义字符
如果需要在正则表达式中插入斜杠,需使用转义字符。注意:字符串中的反斜杠也需要转义。
MATCH (n)
WHERE n.address =~ 'Sweden\\/Malmo'
RETURN n
结果: 'Tobias'返回了,因为他的地址在'Sweden/Malmo'。
3.3.3 正则表达式的非大小写敏感
在正则表达式前面加入(?i)之后,整个正则表达式将变成非大小写敏感。
MATCH (n)
WHERE n.name =~ '(?i)ANDR.*'
RETURN n
结果: 'Andres'被返回了,因为他的名字在不考虑大小写的情况下以'ANDR'开始。
3.4 在WHERE中使用路径模式
3.4.1 模式过滤
模式是返回一个路径列表的表达式。列表表达式也是断言,空列表代表false,非空列表代表true。因此,模式不仅仅是表达式,同时也是断言。模式的局限性在于只能在单条路径中表达它,不能像在MATCH语句中那样使用逗号分隔多条路径,但可以通过AND组合多个模式。
不能在WHERE中的模式引入新的变量。尽管它看起来与MATCH中的模式类似。但MATCH (a)-[]-(b)与WHERE (a)-[]-(b)有很大的不同,前者将产生一个它匹配到的a和b之间路径子图,而后者是排除匹配到的a和b之间没有一个有向关系链的任何子图。
MATCH (tobias { name: 'Tobias'}),(others)
WHERE others.name IN ['Andres','Peter'] AND (tobias)<--(others)
RETURN others
结果: 返回了有外向关系指向'Tobias'的节点。
3.4.2 模式中的NOT过滤
NOT功能可用于排除某个模式。
MATCH (persons),(peter{ name:'Peter'})
WHERE NOT (persons)-->(peter)
RETURN persons
结果: 返回没有外向关系指向'Peter'的节点。
3.4.3 模式中的属性过滤
可以在模式中添加属性来过滤结果。
MATCH (n)
WHERE (n)-[:KNOWS]-({name: 'Tobias'})
RETURN n
结果: 返回与节点'Tobias'有KNOWS关系的所有节点。
3.4.4 关系类型过滤
可以在MATCH模式中添加关系类型,但有时候希望在类型过滤上具有丰富的功能。这时,可以将类型与其他进行比较。例如,下面是一个对关系类型与一个正则表达式进行比较的例子。
MATCH (n)-[r]->()
WHERE n.name='Andres' AND type(r)=~'K.*'
RETURN r
结果: 这个查询返回与节点'Andres'以'K'开始的所有关系。
3.5 列表
3.5.1 IN运算符
检查列表中是否存在某个元素,可以使用IN运算。
MATCH (n)
WHERE a.name IN ['Peter', 'Tobias']
RETURN a
结果: 这个查询检查字符串列表中是否存在某个属性。
3.6 不存在的属性和值
如果属性不存在,对它的判断默认返回false。
对于不存在的属性值就当作null,在下面例子中,对于没有belt属性的节点的比较将返回false。
MATCH (n)
WHERE n.belt = 'white'
RETURN n
结果: 仅返回了belt为white的节点。
3.6.1 属性不存在默认为true的情况
如果要比较的属性存在,则可以与期望的值进行比较。如果不存在(IS NULL),默认值为true。如:
MATCH (n)
WHERE n.belt = 'white' OR n.belt IS NULL
RETURN n
ORDER BY n.name
结果: 返回了满足belt属性值为white和不存在belt属性的所有节点。
3.6.2 空值过滤
有时候需要测试某个值或变量名是否为null。在Cypher中与SQL类似,可以使用IS NULL。相反,“不为空”使用IS NOT NULL,尽管NOT (IS NULL x)也可以。
MATCH (person)
WHERE person.name = 'Peter' AND person.belt IS NULL
RETURN person
结果: 返回name属性值为'Peter'的且不存在belt属性的节点。
3.7 使用范围
3.7.1 简单范围
检查某个元素是否在指定的范围,可以使用不等运算符<, >=和>
MATCH (a)
WHERE a.name >= 'Peter'
RETURN a
结果: 返回节点的name属性值的字典顺序大于或等于'Peter'的节点。
3.7.2 范围的组合
多个不等式可以组合构成一个范围。
MATCH (a)
WHERE a.name >= 'Andres' AND a.name < 'Tobias'
RETURN a
结果: 返回节点的name属性值的字典顺序介于'Andres'和'Tobias'之间的节点。