前言
和学习关系型数据库一样 neo4j最重要的当然还是写语句
因为感觉网络上的文档都不好用 所以决定自己写一个
为了查询方便 推荐使用的老哥们
整一个浏览器的油猴插件 下个目录数脚本
用起来就会丝滑很多
1. 快速入门
学会这个表达式
neo4j就已经入门了
( )代表一个点 , [ ]代表一个关系
()-[]-()
创建一个叫list 的ArrayList的点 ↓
等于ArrayList> list = new ArrayList<>()
一个叫map的HashMap的关系↓
基本上就等于HashMap,?> map = new HashMap<>();
map 这个名称只是临时定义 方便后面可以增加return/delete之类的操作
(list:ArrayList)
[map:HashMap]
一个叫list 的ArrayList的点 他具有size=10 ,value="1 2 3 4 5"的属性
一个叫map的HashMap的关系 他具有size=20, value="
(list:ArrayList{size:10,value:"1 2 3 4 5"})
[map:HashMap{size:20,value:""}]
运行
create
(list:ArrayList{size:10,value:"1 2 3 4 5"})
-[map:HashMap{size:20,value:""}]->
(list2:ArrayList{size:10,value:"1 2 3 4 5"})
return list,map,list2
还记得多少?
嗯?什么?全不记得了?
好的 那么你已经学会了太极拳(neo4j)/doge
2. 基本语句
2.1 NODE CREATE 创建
创建猫节点
CREATE (:)
create (小黑:cat)
书写规则
CREATE (
:
{
:
........
:
}
)
创建一个cat节点定义...属性
CREATE (小小黑:cat{ id:001,name:"ssBlack",age:"3" })
设置cat节点具有的属性(不设置创建节点会自动生成)
create (cat:cid:name:age:gender:class)
可以看出(
2.2 NODE MATCH查询
查询猪妈妈相关的所有信息
match (猪妈妈:pig) return 猪妈妈
查询年龄为11的小猪
match (p:pig{age:11})return p
查询叫佩奇性别为女的小猪
match (p:pig)
where p.name="佩奇"
and p.gender="girl"
return p
查询age =11或者name=猪爸爸的节点
match (p:pig)
where p.age =11 or p.name="猪爸爸"
return p
2.3 NODE MATCH&RETURN数据表格
数据表格
查询所有小猪的姓名和年龄
match (p:pig)
return p.name,p.age
查询person具有哪些关系 关系名叫啥
match (a:person)-[r]->(b)
return r,type(r)
/doge
查询小红帽混乱的人物关系
match (a:person{name:"小红帽"})-[r]->(b)
return a,b,r,type(r)
2.4 NODE DELETE删除
ps:删除点的时候 如果存在关系的话 删不掉 得先删除关系
#创建一个showmaker节点 写上他的信息
create (e:showmaker{name:"faker",id:001})
return e
#detach 可以删除改点的相关关系 然后删除点(常用)
match (a:showmaker) detach delete a return a
#删除所有showmaker节点
match (a:showmaker)
delete a
return a
查询一个showmaker名字叫做777
match (e:showmaker)
where e.name="777"
return e
稍微改装一下 就是删除
match (e:showmaker)
where e.name="777"
delete e
由此我们更加可以看出 e(node-name)是用来作为调用使用的 类似于指针 或者说别名
ps :Edge/Relationship =边/关系)
2.5 EDGE CREATE创建
create (c:cat{cid:001,name:"罗小黑",cid:001,age:12})
创建一个cat和pig的关系(等同于java创建空对象)
CREATE (n1:cat)-[r1:likes]->(n2:pig)
给狼人(wolf)-和->村长(sheep)创建关系
match (s1:sheep),(w1:wolf)
where s1.name="村长" and w1.name="狼人"
create (w1)-[r:`狼人杀`{type:"game",time:"2021/1/16"}]->(s1)
return r
万一添加错了删掉
match (s1:sheep),(w1:wolf)
where s1.name="村长" and w1.name="狼人"
optional match s1-[r]->w1
delete r
嗨呀 一不小心就透露了删除边的写法
2.6 MERGE 如果不存在就创建
merge会自动根据id去重 ,重复属性id值的 不会添加
如图我们发现只有faker在
#创造7酱!
merge(n:showmaker{id:2,name:"777"})
再次创造7酱! 已经存在了 就不能创造了
2.7 EDGE DELETE 删除
相关的节点关系全部删除
MATCH (cc: CreditCard)-[rel]-(c:Customer)
DELETE cc,c,rel
用楼上的方法 会删除所有->和查询条件相符的关系
当时只需要删除一个的时候可以使用关系的唯一id(不是自己设置的属性,neo4j自带的唯一标识)
match ()-[r]->()
where id(r)=125
delete r
2.8 REMOVE删除属性
#查看该点的信息
match (s:showmaker{id:1})
return s
#删掉该点的id信息
match (s:showmaker{id:1})
remove s.id
return s
2.9 SET设置/更新属性
想变回来怎么办
#恢复刚刚的点信息
match (n:showmaker {name:"faker"})
set n = {name:"faker",id:1}
return n
加上给所有该label的点添加属性
# 给每个学生 添加上木叶村属性
match (student:Student)
set student.country = "木叶"
return student
2.10 LIMIT&SKIP截取和跳过
原理和上一篇stream流一样
过于简单就不说了
我个人觉得和排序一起用会比较爽
#根据年龄正序排列 但是去掉前面两个
MATCH (n:pig)
return n.name, n.age
order by n.age asc
skip 2
2.11 分页
利用skip和limit我们很容易就达成分页了啦
skip=page*pagesize //当前页X每页条数
limit=pagesize //每页条数
#每页两个数据 当前第三页
MATCH (n:pig)
return n.name, n.age
order by n.age asc
skip 4
limit 2
2.12 NULL 空属性
neo4j是允许属性为空的
创建一个点但是不设置任何属性
create (a:showmaker)
当当! 就会出现这么一个鬼东西
is not null 自如其名
查询不为空的点
MATCH (n:showmaker)
where n is not null
RETURN n LIMIT 25
我们可以发现 这个点是存在的 只是属性没有而已
查询属性为空的点
查询name属性不为空的点
MATCH (n:showmaker)
where n.name is not null
RETURN n LIMIT 25
就可以筛选掉某些属性为空的数据
通常我们用java的话 就可以通过语句
减少在neo4j中获取的空数据
就不用去java里面判空了 也减少了数据库连接中传输数据的大小
2.13 IN 范围查询
道理和sql差不多 规范是 in [a , b, c]
查询年龄在100 60 55的小猪
match (a:pig)
where a.age in [100,60,55]
return a
2.14 排序order by
老排序了 和sql一样用
# 正序排列
match (w:wolf)
return w.name, w.age
order by w.age asc
#倒序排列
match (w:wolf)
return w.name, w.age
order by w.age desc
2.15 = ~".* XXX .*" 模糊查询
neo4j里面规定的like写法有点奇怪
= ~".* XXX .*"
查询*太*的点信息
match (a)
where a.name =~".*太.*"
return a
查询结果:
2.15 逻辑运算,等于,不等于,与或非,异或
3. CQL函数
3.1 字符串函数
不多说什么了 neo4j是java写的 懂的都懂/doge
3.1.1 UPPER&LOWER字母大小写
把name变成大写
MATCH (n:showmaker)
RETURN n.id,upper(n.name )as name
LIMIT 25
3.1.2 SUBSTRING截取
ps:左闭右开
把spring截取faker [0,2)左闭右开
MATCH (n:showmaker)
RETURN n.id,substring(upper(n.name),0,2)as name
LIMIT 25
3.2 AGGREGATION聚合函数
重点!重点!拿笔拿本子了!
3.2.1 COUNT数量
查询年纪在[50,80)之间的小猪的数量
MATCH (n:pig)
where 80>n.age>=50
RETURN count(*)
ps:为了减少产生db连接而合成cql是有问题的
这样写有问题!
MATCH (n:pig)
where 80>n.age>=50
RETURN count(*), n
超级函数
/**
* 统计所有节点类型和数量 比普通查询语句速度快很多
*/
public static final String STATISTICS_ALL_LABELS_TYPE_AND_COUNT_CQL = "call apoc.meta.stats() yield labels return labels;";
3.2.2 MAX&MIN最大最小
找出小猪最大年纪和最小年纪
MATCH (n:pig)
RETURN max(n.age),min(n.age)
3.2.3 SUM&AVG求和 平均
MATCH (n:pig)
RETURN sum(n.age) as sum,avg(n.age) as avg ,count(*) as count
3.3 关系函数
3.3.1 STARTNODE&ENDNODE 开始点/结束点
找出是对手->关系的开始点 和结束点
match (a)-[r:`对手`]->(b)
return startnode(r),endnode(r)
其实和return a,b结果是一样的 不知道有啥特殊的 以后知道了再写上来把
match (a)-[r:`对手`]->(b)
return a,b
3.3.2 ID&TYPE&LABLES id和类型
查询对手关系的id 和type 和点的类型
match (a)-[r:`对手`]->(b)
return id(r),type(r),labels(b)
在多个label中查询
match (a)
where a.id="57-(674)689-9732" and (a:user or a:contact)
return a
前者比后者快百倍
match (n)
where any(label in labels(n) where label in ["contact",""])
and n.id ="57-(674)689-9732"
return n
延伸 查询节点信息
match (a)
where a:contact or a:Email
return distinct keys(properties(a))
3.4 特殊函数
FOREACH 遍历
类似于mybatis的动态sql
//将下列列表的人全部添加为A的朋友
MATCH (a:Person{name:A})
FOREACH (name IN ["Mike","Carl","Bruce"])
CREATE (a) - [:FRIEND]->(:Person:{name:ma,e})
4. 不常用分割线
4.1 UNION不同点同时查询
# 强行把两个节点数据 放在一张表
match (p:person)
return p.name as name ,p.id as id
union
match (s:showmaker)
return s.name as name ,s.id as id
5.业务语句
5.1 关系更改名字
#修改实体label:
match(n:oldlabel) set n:newlabel remove n:oldlabel
#修改关系label(将关系subord 修改为 subord_new):
MATCH p=(n:User)-[r:subord]->(e:department) create(n)-[r2:subord_new]->(e) set r2 = r with r delete r
5.2 查询多级关系
#查询喜羊羊的所有关系 直到终点
match data = (a:Sheep{name:"喜羊羊"})-[*]->()return data
#查询喜羊羊到别的节点 路径上所有like关系的节点
match data = (a:Sheep{name:"喜羊羊"})-[:like*]->()return data
#查询喜羊羊到别的节点 查询3个层级 路径上所有like关系的节点
match data = (a:Sheep{name:"喜羊羊"})-[:like*1..3]->()return data
#查询喜羊羊到别的节点 查询3个层级 路径上所有like关系的节点的所有两层关系节点
match data = (a:Sheep{name:"喜羊羊"})-[:like*1..3]->()-[*1..2]-()return data
apoc 查询
match (p1)-[]-(p2)
where p1.id in ['喜洋洋']
and
p2.id in ['灰太狼']
and
any(label in labels(p1) where label in ["Sheep"])
and
any(label in labels(p2) where label in ["Sheep"])
with p1,p2
call apoc.path.expandConfig(p1,
{
minLevel:0,
maxLevel:2,
relationshipFilter:'Friend|Like',
endNodes:p2,
limit:100
})
yield path as data return data limit 50
5.3 删除所有索引
#查看索引
:schema
#删除所有索引
CALL apoc.schema.assert({}, {})
后言
感谢 w3cschool让我思路清晰了 很多
https://www.w3cschool.cn/neo4j/neo4j_cql_relationship_functions.html
感谢《Neo4j权威指南》张帜
一直在更新 希望做出来的文档好用
有啥觉得用着不舒服的 欢迎辱骂
后期有空会出APOC API使用的博客 如果考完有空的话emm