neo4j学习记录
Neo4j
借鉴文章地址:www.cnblogs.com/1314h/p/150…
一、基础概念
节点:
节点是图数据库中的一个基本元素,表示一个具体的实体,可以类比成关系数据库中的记录
Cypher 采用一对圆括号 () 来表示节点,如 (n:角色) 表示一个 角色 节点,n 是变量名,供命令执行时用 n 来访问这个节点,在命令执行完毕后就无法使用了。同时单独的 () 表示一个匿名节点,在匹配时表示匹配所有节点。
标签:
标签(label)是同一类节点的组合,但是并不是在同一标签下的节点一定包含相同属性。
关系:
关系是图数据库中节点之间的连接,也表示成节点之间的边,neo4j中关系是双向的。
在关系中:
--表示无方向的关系
--> 表示有方向的关系
-[r]-> 则给关系赋予一个变量名,方便对这个关系进行操作
-[r:KNOWS]-> 匹配关系类型为 KNOWS 的关系,KNOWS被称为关系的类型
路径:
路径是图数据库建立之后,任意两个节点之间的连通管理,是关系的组合。
属性:
属性是对节点以及关系的一种说明,可以类比成关系数据库中的字段或者列,这里需要强调的是,在图数据库中关系也是可以设计属性的。
Neo4j CQL支持以下数据类型:概括为布尔值、整型、浮点型、字符
| CQL数据类型 | 用法 |
|---|---|
| boolean | 用于表示布尔文字:true,false。 |
| byte | 用于表示8位整数。 |
| short | 用于表示16位整数。 |
| int | 用于表示32位整数。 |
| long | 用于表示64位整数。 |
| float | I用于表示32位浮点数。 |
| double | 用于表示64位浮点数。 |
| char | 用于表示16位字符。 |
| String | 用于表示字符串。 |
比较运算符
| 运算符 | 说明 |
|---|---|
| = | 等于,注意是一个“=”号,不是两个 |
| <> | 不等于 |
| < | 小于 |
| 大于 | |
| <= | 小于等于 |
| >= | 大于等于 |
逻辑运算符
| 逻辑运算符 | 说明 |
|---|---|
| AND | 与 |
| OR | 或 |
| NOT | 非 |
| XOR |
二、cypher语言快速入门
cypher是一种非常简洁的图查询语言,可以在shell与浏览器端直接执行。其基本语法包含以下四个部分:
start:设定查找的起始节点(在新版本的neo4j中start可以省略)
match:匹配图形模式, 可以定位感兴趣数据的子图形
where:对查询数据进行过滤
limit:限制查询数量
return:返回结果
三、命令
常用命令
| CQL命令 | 用法 |
|---|---|
| CREATE 创建 | 创建节点,关系和属性 |
| MATCH 匹配 | 检索有关节点,关系和属性数据 |
| RETURN 返回 | 返回查询结果 |
| WHERE 哪里 | 提供条件过滤检索数据 |
| DELETE 删除 | 删除节点和关系 |
| REMOVE 移除 | 删除节点和关系的属性、节点的标签 |
| ORDER BY以…排序 | 排序检索数据 |
| SET 设置 | 添加标签,修改属性 |
| AS 起别名 | 最后为指定的节点或关系起一个别名 |
常用函数
| 定制列表功能 | 用法 |
|---|---|
| String 字符串 | 它们用于使用String字面量。 |
| Aggregation 聚合 | 它们用于对CQL查询结果执行一些聚合操作。 |
| Relationship 关系 | 他们用于获取关系的细节,如startnode,endnode等。 |
1、增
1、创建节点
create (n:Person {name:"Emil", from: "Sweden", klout: 99})
create (:Person {name:"test1", from:"Null", klout: 0}),(:Person {name:"xiaoming", age:18}),(:Person {name: "xiaohong", age: 17}),(:Person {name: "xiaolan", age: 17})
create,关键字,表示创建
()代表一个节点
n表示一个临时变量名称后面如果使用不到该节点,可以不写
Person为赋予该节点的标签名
{}表示节点的属性,里面填写具体的属性值
2、创建关系,必须要指明关系的类型和关系的方向,否则关系无法创建
1)、在两个已存在节点之间创建关系
match (n:Person {name:"test1"}),(nn:Person{name:"Emil"}) with n,nn create (n)-[:KNOWS]->(nn)
match (n:Person),(nn:Person) where n.name="xiaoming" and nn.name="xiaohong" create (n)-[:KNOWS]->(nn)
match (n1:Person {name: "xiaoming"}),(n2:Person {name: "xiaohong"}),(n3:Person) where n3.name="xiaolan"
create (n1)-[:KNOWS]->(n3),(n2)-[:KNOWS]->(n3),(n3)-[:KNOWS]->(n2)
2)、一个已存在节点和一个新节点之间创建节点的关系
match (n:Person {name: "test1"}) create (nn:Person {name: "test2"}),(nn)-[:KNOWS {since: 2020}]->(n)
match (n1:Person {name:"test1"}),(n2:Person {name:"test2"}) create (n3:Person {name:"test3"}),(n3)-[:KNOWS {since:2011}]->(n1),(n3)-[:KNOWS {since: 2022}]->(n2)
match (n1:Person),(n2:Person) where n1.name="xiaoming" and n2.name="xiaohong" create (n3:Person {name:"xiaohui", age:17}),(n2)-[:KNOWS]->(n3),(n1)-[:KNOWS]->(n3)
3)、在两个新节点之间创建关系
create (n1:Person {name:"test1"})-[r:KNOWS {since:2022}]->(n2:Person)
MATCH (ee:Person) WHERE ee.name = "Emil"
CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }),
(ir:Person { name: "Ian", from: "England", title: "author" }),
(rvb:Person { name: "Rik", from: "Belgium", pet: "Orval" }),
(ally:Person { name: "Allison", from: "California", hobby: "surfing" }),
(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir),
(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb),
(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally),
(rvb)-[:KNOWS]->(ally)
3、创建属性(设置属性,修改属性也是此方式操作)
match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" set r.end=2012 return n,nn
4、创建标签(添加标签)
create (n {name: "Lone"}) // 创建一个节点,没有标签,有一个属性name
match (n {name: "Lone"}) set n:Person return n // 节点本来没有标签,新增一个Person标签
match (n) where n.name="Lone" set n:Student return labels(n) // 节点有一个Person的标签,再新增一个Student标签
2、删
1、删除节点
1)、删除一个没有任何关系的独立节点(此节点没有任何关系存在)
match (n:Person {name: "Lone"}) delete n
2)、删除一个存在关系的节点
当一个节点有关系存在时,只使用delete删除会报错,操作不成功,此时需要使用detach关键字,但这种删除会将此节点涉及的所有关系一并删除
match (n:Person {name: "test2"}) detach delete n
2、删除关系
match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="test3" and nn.name="test1" delete r
3、删除属性
match (n:Person) where n.name="xiaoming" remove n.age return n
match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" remove r.end return n,r,nn
4、删除标签
match (n:Person) where n.name="test3" remove n:Person return n
5、清空数据库
1)、命令删除,此种方式会先读取数据,再删除,所以不适用于数据库数据太大的情况
match (n) detach delete n
2)、操作删除,找到数据库文件夹直接删除
3、改
1、修改属性,节点和关系的属性修改方式一样
match (n:Person) where n.name="xiaoming" set n.name="XiaoMing" return n
match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" set r.since=2000 return n,nn
2、修改节点的标签
无法直接修改,需要先删除要修改的标签,再增加新的标签
match (n) where n.name="test1" remove n:Person set n:Student return n
3、修改关系类型
无法直接修改,需要先创建新类型的关系,新关系可以复制老关系的属性(属性不变则复制,属性变化则从新设置),最后将老关系删除,
match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" create (n)-[r2:LIKES]->(nn) set r2=r delete r
4、查
4.1 简单查询
1、查找节点(包含了id、标签和属性)
1)、只涉及节点属性的查找
match (n) return n // 查找所有节点,有显示上限
match (n:Person) where n.name = "Emil" return n // 通过节点的属性过滤,返回匹配的节点信息
match (n:Person {name: "Emil"}) return n
// n
// {
// "identity": 0,
// "labels": [
// "Person"
// ],
// "properties": {
// "name": "Emil",
// "from": "Sweden",
// "klout": 99
// }
// }
match (n:Person) where n.name = "Emil" return properties(n) // 通过节点的属性过滤,只返回匹配节点的属性
// properties(n)
// {
// "name": "Emil",
// "from": "Sweden",
// "klout": 99
// }
match (n:Person) where n.name = "Emil" return labels(n) // 通过节点的属性过滤,返回节点的标签
// labels(n)
// ["Person"]
match (n:Person {name:"Emil"}) return id(n) // 返回节点的id
// id(n)
// 0
match,关键字,表示匹配查询
n表示一个临时变量名称后面如果使用不到该节点,可以不写
Person表示查找的节点的标签名称为“Person”
where,关键字,过滤功能
n.name = "Emil",过滤条件,表示要查找的节点的属性中的name要为"Emil"
return,返回数据
properties(n)表示节点n的属性,labels(n)表示节点n的标签
2)、涉及节点关系的查找
A、查找时指明关系方向
match (n:Person)-[:KNOWS]->(friends) where n.name = "Johan" return n,friends // 返回的是节点所有数据,只需要属性的话加properties(n)
match (n)-[r:KNOWS|LOVE]-(nn) return n,nn
B、查找时不指明方向:和上面的命令类似,只是没有指明关系方向
match (n:Person)-[:KNOWS]-(friends) where n.name = "Johan" return n,friends
⭐模式匹配可以用来做推荐. Johan 正在学 冲浪, 因此他想找到一个冲浪的新朋友:
MATCH (js:Person)-[:KNOWS]-()-[:KNOWS]-(surfer) WHERE js.name = "Johan" AND surfer.hobby = "surfing" RETURN DISTINCT surfer
⭐要了解查询的流程, 可在查询之前加 EXPLAIN 或 PROFILE:
explain MATCH (js:Person)-[:KNOWS]-()-[:KNOWS]-(surfer) WHERE js.name = "Johan" AND surfer.hobby = "surfing" RETURN DISTINCT surfer
2、查询关系(包含了类型和属性)
match (n:Person)-[r:KNOWS]->(friends) where n.name = "Johan" return r
4.2 复杂查询
1、起始节点和结束节点之间不直接相连,中间存在其它节点,且路径不唯一
match (n:Person {name:"Emil"})-[r:KNOWS*3]->(nn:Person {name:"Allison"}) return r
// match (n:Person {name:"Emil"})-[r*3]->(nn:Person {name:"Allison"}) return r
// match (n:Person {name:"Emil"})-[r*2..3]->(nn:Person {name:"Allison"}) return r 不定长关系
// r:KNOWS*3代表 从n到nn要经过三个关系(三条边)
// 返回了一个列表,里面有两条数据,即有两种方案
[
{
"identity": 7,
"start": 0,
"end": 8,
"type": "KNOWS",
"properties": {
"since": 2000
}
}
,
{
"identity": 12,
"start": 8,
"end": 9,
"type": "KNOWS",
"properties": {
}
}
,
{
"identity": 15,
"start": 9,
"end": 11,
"type": "KNOWS",
"properties": {
}
}
]
[{ "identity": 7, "start": 0, "end": 8, "type": "KNOWS", "properties": {"since": 2000 }}, { "identity": 13, "start": 8, "end": 10, "type": "KNOWS", "properties": { }}, { "identity": 16, "start": 10, "end": 11, "type": "KNOWS", "properties": { }}]
2、模糊查询
1)、模糊匹配对象
match (n:Person) where n.name=~".*Em.*" return n // 使用=~进行模糊匹配查询,正则匹配
match (n) where n.name=~".*Ming.*|.*hong.*" return n
match (n) where n.name=~".*Ming.*" or n.name=~".*hong.*" return n
2)、contains
match (n) where n.name contains "Ming" return n // 名字中包含Ming的人(节点)
3)、starts with
match (n)-[r]->(nn) where n.name starts with "E" return distinct n
// 查询节点名字是E字母开头的人,并且去重,因为n认识两个人,所以匹配到了两次,不加入关系的话匹配到一次
match (n) where n.name starts with "E" return n
4)、ends with
match (n)-[r]->(nn) where n.name ends with "an" return distinct n
match (n) where n.name ends with "an" return n
四、扩展
1、支持列表
return range(0, 10) as list // 注意这里左闭右闭
// list
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
return range(0, 10)[-3] as list // 支持索引
// list
// 8
return range(0, 10)[0..3] as list
// list
// [0, 1, 2]
return range(0, 10)[11] as list
// list
// null
2、计算列表长度
return size(range(0, 10))
// size(range(0, 10))
// 11
3、MERGE
MERGE = CREATE + MATCH
MERGE命令在图中搜索给定模式,
如果存在,则返回结果
如果它不存在于图中,则它创建新的节点/关系并返回结果