Neo4j图数据库学习手册
为什么需要图数据库?
现在,业务需求的频繁变动和数据之间的复杂联系都需要数据库有很强的适应力。对于传统关系型数据库,对于复杂的数据关系并不能很好的展现。比如社交网站的用户关系,错综复杂就像一张网 。对于这种数据,图数据库就能很好以图结构来存储。
联系才是数据本质的存在
聊聊neo4j的CQL操作
CQL
CQL是neo4j的图形查询语言。【Cyther(友情提示:赛粉儿) Query Language】
图数据库有什么?
最简单的回答:点和边啊!
正经一点回答:点代表一个节点信息,边代表节点信息之间的关系。点和边都可以具有属性,以键值对的形式。
创建节点
语法结构:create (<node-name>:<label-name>)
节点名称、标签名称。
create (p:phone) //创建了一个没有属性的节点,这个节点是个phone,具体是什么phone看使用者是如何定义了
create (p:phone{type:"phone",phoneNumber:"181XXXX3333"}) //创建了一个有属性的节点,想必这种形式大家不陌生。对,就是你们想的那样。并且,type也只是属性之一,并不是必须的。
按照以上格式,我们可以创建多个。如果想要在创建的时候看到创建结果可以在后面追加
return p;
create (p:phone) return p;
eg2:
create (b:bag{color:"red"}),(b2:bag{color:"green"})
创建关系
关系是节点与节点之间的关联。
关系分为单向和双向。创建关系时请带上箭头>或者<。
语法:
match:匹配
where:在某某条件前提下
return:返回一个而结果,返回什么由后面内容决定
在明确这些前提之后。我们可以这样:
- 已有节点之间创建无属性的关系
eg1:
match (p1:phone{phone:"18145626687"}),(p2:phone{phone:"13415556888"})
create (p1)-[r:call]->(p2)
return r;
eg2:
match (b1:bag{color:"red"}),(b2:bag{color:"green"}) create (b1)-[r:mixWith]->(b2) return r;
根据上列CQL,相信大家还是能读懂字面意思。就是我要match俩phone节点,他们分别是具有某某电话的属性。然后我create一个链路,从p1到p2,中间中括号是r:call,还有个方向键。
即创建一个关系,这个关系是从a到b的,然后关系的名字是call。
其中p1和p2就像是对象一样,随便叫什么。
同理,我们还可以有另一种写法,把where用上
match (p1:phone),(p2:phone)
where p1.phone="18145626687" and p2.phone="13415556888"
create (p1)-[r:call]->(p2)
return r;
//创建关系
- 已有节点之间创建有属性的关系
match (p1:phone),(p2:phone)
where p1.phone="18145626687" and p2.phone="13415556888"
create (p1)<-[r:call{sumTime:"30.22",counts:"3"}]-(p2)
return r;//可要可以不要这一句,只是看看返回结果
- 没有节点,直接创建节点和关系
create (h1:hero{name:"ez",age:"18"})-[r:loves{loveTime:"10"}]->(h2:hero{name:"lux",age:"16"})
查询
语法:match 匹配 + return 返回
单独使用match是会报错的,因为只是匹配没有返回
where 用于筛选条件
with 在return之前进行特殊处理,值得注意的一点是如果return返回某个值,这个值要在with中申明。
//普通查找节点
match (pn:hero) where pn.name="ez" return pn;
match res=(pn:hero) where pn.name="ez" return res;
match (pn:hero{name:"ez"}) return pn;
//排序查找节点
match res=(p1:hero) return res order by p1.age desc;
//普通查找关系
match res = (p1:hero{name:"ez"})-[r:loves]->(p2:hero) return res; //返回ez爱上了谁,
match res = (p1:hero{name:"ez"})<-[r:loves]-(p2:hero) return res; //返回谁爱ez,
match res = (p1:hero{name:"ez"})-[r:loves]-(p2:hero) return res; //返回谁和ez相爱了,
match res = (p1:hero{name:"ez"})-[r:loves]-() return res; //返回ez喜欢的任何东西,除了人还有其他的,
聚合查找
with 在where后对搜索结果进行二次处理时需要用到
distinct 去重,可以对节点去重也可以对节点的属性去重
as 重命名(和sql一样)
count(*)计数
sum(属性值的累加) avg、min、max
没有group by。
这里随便写一个
match res=(p1:hero{name:"ez"})-[r:loves]->(p2:hero) with distinct p2.name as lover return p1,lover; //返回ez和ez爱上的人,并且出现同名的则只要显示一个名字就可以了
删除节点、关系
delete 删除节点或者关系,删除节点时,如果存在关系则删不掉
match (p:hero{name:"lux"}) delete p;
Neo.ClientError.Schema.ConstraintValidationFailed: Cannot delete node<106743711>, because it still has relationships. To delete this node, you must first delete its relationships.
match (p1:hero{name:"ez"})-[r:loves]->(p2:hero{name:"lux"}) delete r,p2; //删除关系r和节点p2。ez不爱拉克丝了。
待续。。。。