哈啰,各位小伙伴们,这里是每天进步一点点的花栗鼠小K
上期小K介绍了Neo4j的基础语法,本期小K想带领各位小伙伴上一个台阶,所以在这一期,我们将继续从Neo4j讲起,来介绍一些高级语法。
CQL 高级语法
case 语句
case
条件表达式有两种,一种类似于if/else
,另一种类似于case/when
if/else
型return
case
when 1=2 then 1
when 2=2 then 2
when 3=3 then 3
else 4
end做区间判断或者需要比较不同的字段的时候使用
case/when 型
return
case 3
when 2 then 2
when 3 then 3
when 4 then 4
else 0
end在使用的时候,我们常常通过match找到某个节点,对某个属性字段做不同处理
数学函数
ABS( expression )
返回expression得到的数值的绝对值ROUND( expression )
取整函数:返回小于等于expression得到的数值的最大整数(还是返回离expression得到的数值最近的整数??)SQRT( expression )
返回expression得到的数值的平方根SIGN( expression )
符号函数:如果expression得到的数值,为0则返回0;为负数则返回-1;为正数则返回1集合函数
NODES( path )
返回一个路径的所有节点MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
RETURN nodes(p)RELATIONSHIPS( path )
返回一个路径的所有关系MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
RETURN RELATIONSHIPS(p)EXTRACT( identifier in collection | expression )
返回一个结果集合:对集合(collection)的所有元素执行expression的操作得到的结果MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
with nodes(p) as x
RETURN extract(xi in x | xi.islive=false)FILTER(identifier in collection WHERE predicate)
返回集合(collection)中所有满足断言(predicate)的元素组成的集合MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
with nodes(p) as x
RETURN extract(xi in x where xi.islive=false)ALL(identifier in collection WHERE predicate)
当集合(collection)中所有元素满足断言(predicate) ,返回trueMATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
with nodes(p) as x
with all(xi in x where xi.islive=false) as result
RETURN resultcatelyn、drogo分别对应name为Catelyn、Drogo的节点的别名
ANY(identifier in collection WHERE predicate)
当集合(collection)中任意一个元素满足断言(predicate) ,返回trueMATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
with nodes(p) as x
with any(xi in x where xi.islive=false) as result
RETURN resultNONE(identifier in collection WHERE predicate)
当集合(collection)中没有一个元素满足断言(predicate) ,返回trueMATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
with nodes(p) as x
with none(xi in x where xi.islive=false) as result
RETURN resultSINGLE(identifier in collection WHERE predicate)
如果集合(collection)里的只有一个元素满足断言(predicate)则返回trueMATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
with nodes(p) as x
with SINGLE(xi in x where xi.islive=true) as result
RETURN resultTAIL( expression )
返回集合中除了第一个之外的所有元素RANGE( start, end [, step] )
返回从start开始,end结束(闭区间)内步长为step(非0)的所有整数数字列表
CQL
语言中的列表和 Python 中的列表很相似都使用[]
,都可以包含不同的元素,直接使用return
创建range
用法
range(start, end, step)
列表索引
下标索引:RETURN[[1,2,3,4][1] ][] 返回2
范围索引:RETURN [[1,2,3,4]][[1..3][1..3] //返回[2,3],注意返回的是列表,不包括4
范围索引:RETURN [1,2,3,4][-2..] 返回[3,4]
越界索引:RETURN [1,2,3,4][2..9] //只返回[3,4]
越界索引:RETURN [1,2,3,4][7..9] //返回一个空列表 []
越界索引:RETURN [1,2,3,4][9] //单个元素越界索引,返回 null
列表推导
列表推导是 Cypher 基于已有列表创建新的列表,可以和 where 等语句一起使用。功能类似于 Python 的 map 操作,也类似于 lambda 表达式,形式看起来和 linux 管道符号
|
一样,作用也类似,前面的输出作为后面的输入。RETURN [x in range(1,3) | x^2]
列表函数
reverse
:将list进行反转tail
:列表的第一个元素默认为 head,tail
函数输出除了头意外的其余函数特殊查询
省略关系
match(n)-->(m)
两个
-
表示省略任意关系match(a:Man)-->(b:Woman)
return a,b匹配多种关系类型
match(n)->[:A|:B]->(m)
匹配A或者B类型的关系
match(a:Man)-[:I_says|:Marriage]->(b:Woman)
return a,b带有空格的关系
match(n)-[
A B
]->(m)match(a:Man)-[`I_says Marriage`]->(b:Woman)
return a,b变长关系
match(n)-[r:Relationship*a..b]-(m)
match(n:Character{name:"Eddard"})-[r:INTERACTS*1..2]-(m:Character)
RETURN m.name最短路径
match(n),(m),p=shortestPath((n)-[*..N]-(m)) return p
查找 n,m 之间的最短路径,路径最大长度为N
MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}), p=shortestPath((catelyn)-[INTERACTS*..3]-(drogo))
RETURN p
MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
RETURN p所有最短路径
match(n),(m),p=allShortestPaths((n)-[*]-(m))
查找n,m之间所有最短路径
MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=allShortestPaths((catelyn)-[*]-(drogo))
RETURN pid 查询
match(n) where id(n)=1 return n
OPTIONAL MATCH
可选择的
match
match(n:Person{name:"p1"}),(m:Person{name:"p2"}) return n,m
MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"})
return catelyn,drogo
MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Loken"})
return catelyn,drogo加入
OPTIONAL
之后MATCH (catelyn:Character {name: "Catelyn"})
optional match (drogo:Character {name: "Loken"})
return catelyn,drogo但还是有一定的要求,
match
必须有东西optional MATCH (catelyn:Character {name: "Loken"})
optional match (drogo:Character {name: "Drogo"})
return catelyn,drogowhere 标签过滤
match(n:Person) return n match(n) where labels(n)=["NodeTypeName"] return n match(n) where n:NodeTypeName return n
match(n)
where labels(n)=["Man"]
return n
match(n)
where n:Man
return n属性存在检查
exists
函数支持属性检查判断属性是否存在。 match(n) where exists (n.name) return nmatch (n:Man)
where exists(n.name)
return n字符串匹配
STARTS WITH
、ENDS WITH
、CONTAINS
支持字符串匹配(注意是大小写敏感)match (n:Character)
where n.name starts with "Ca"
return n
match (n:Character)
where n.name ends with "yn"
return n
match (n:Character)
where n.name contains "yn"
return n支持反向操作
not
where 路径模式
传统的,比如查找指向凯特琳的节点,我们使用
match
match(n:Charachter)-->(catelyn:Character{name:"Catelyn"}) return n
如何查找都不指向凯特琳的节点呢?需要用where
type 匹配关系类型
这个和
where
标签过滤类似,但是后者是针对于节点,type
是针对于关系标签,不支持match (n:Character)-[R]->(cat:Character{name:"Catelyn"})
where TYPE(R)="INTERACTS"
return ncypher正则表达式
cypher
正则标识是=~ ,‘.*’
表示任意字符mysql
中的like,%
表示任意长度字符,_
表示任意单个字符match (n:Character)
WHERE n.name =~".*do.*"
return n因为正则表达式可能会遇到特殊字符,有时候需要转义,使用
\
CQL
正则表达式提供了更强大的一些功能,比如不区分大小写(?i
)、多行(?s
)等match (n:Character)
WHERE n.name =~"(?i)cat.*"
return n
return 'w1w2\nt3w3w4' =~ '.*w3.*'
return 'w1w2\nt3w3w4' =~ '(?s).*w3.*'索引与约束
添加索引:CREATE INDEX ON :label_name(property) 删除索引:DROP INDEX ON :label_name(property)
create index on :Red_D(name)
drop index on :Red_D(name)
match(n:Red_D)
WHERE n.name="贾宝玉"
return n创建一个唯一约束保证图数据库中同一个标签内的节点的属性值不重复
CREATE CONSTRAINT ON (n:NodeTypeName) ASSERT n.property IS UNIQUE
Drop CONSTRAINT ON (n:NodeTypeName) ASSERT n.property IS UNIQUEUNWIND 和 FOREACH
With
UNWIND
, you can transform any list back into individual rowsunwind range(1,9,2) as x
return x列表去重
unwind [1,1,2,2,3,5] as x
with distinct x
return x遍历多个列表
WITH [1, 2] AS a,[3, 4] AS b
UNWIND (a + b) AS x
RETURN xunwind 嵌套
WITH [[1, 2],[3, 4], 5] AS nested
UNWIND nested AS x
UNWIND x AS y
RETURN y空列表
不返回任何东西,注意不是返回null。
路径遍历
match p=(n:Person{name:"p1"})-[*1..5]-(m)
unwind nodes(p) as x
return xThe
FOREACH
clause is used to update data within a list, whether components of a path, or result of aggregation.MATCH p =(begin)-[*]->(END )
WHERE begin.name = 'A' AND END .name = 'D'
FOREACH (n IN nodes(p)| SET n.marked = TRUE )可以执行
CREATE UNIQUE
,MERGE
,DELETE
,等更新语法,还可做foreach嵌套。cypher 时间处理
date
date函数默认返回当前时区的当前日期,如: RETURN date() 结果:"2019-05-24" 。具体使用方法如下:
date() 当前时区当前日期
date({ timezone: 'America/Los Angeles' }) //指定时区日期
date({ year:1984, month:10, day:11 }) //指定日期
date({ year:1984, week:10, dayOfWeek:3 })
date({ year:1984, quarter:3, dayOfQuarter: 45 })
date({ year:1984, ordinalDay:202 })
date('2015-07-21')
date('2015-07')
date('201507')
date('2015-W30-2')
date('2015202')
date('2015')datetime
datetime() //当前时间
datetime({ timezone: 'America/Los Angeles' })
datetime({ year:1984, month:10, day:11, hour:12, minute:31, second:14, millisecond: 123, microsecond: 456, nanosecond: 789 })嵌套查询
简单子查询
match (c:X_Person)
where exists{
match (c)-[:师傅]->(:X_Person)
}
return c带 where 的子查询
match (c:X_Person)
where exists{
match (c)-[:师傅]->(:X_Person)
where c.age>100
}
return c嵌套存在子查询
MATCH (X:X_Person)
WHERE EXISTS {
MATCH (X)-[:师傅]->(Y:X_Person)
WHERE EXISTS {
MATCH (Y)-[:has]->(W:X_Wuqi)
WHERE W.name = '金箍棒'
}
}
RETURN X.name as name文件的导入
load csv with headers from "路径" as rows
merge (head:R_D{name:rows.head})
merge (tail:R_D{name:rows.tail})
create (head)-[r:Red_Relation{name:rows.relation,label:rows.label}]->(tail)
return r
总结
本期主要讲述了 Neo4j
的高级语法,从case语句到文件导入,详细地介绍 Neo4j
中高阶的命令,高阶命令是针对于更复杂场景的杀器,熟练使用高阶命令,对于处理社交网络等现实场景有很大便利,希望对感兴趣的小伙伴有所帮助。
本期就到这了,这里是花栗鼠小K,下次有🌰,我再来,拜拜~~~
关注六只栗子,面试不迷路!
作者 花栗鼠小K
编辑 一口栗子