neo4j学习记录

154 阅读9分钟

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位整数。
floatI用于表示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)

image

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

image

​ B、查找时不指明方向:和上面的命令类似,只是没有指明关系方向

match (n:Person)-[:KNOWS]-(friends) where n.name = "Johan" return n,friends

image

⭐模式匹配可以用来做推荐. Johan 正在学 冲浪, 因此他想找到一个冲浪的新朋友:

MATCH (js:Person)-[:KNOWS]-()-[:KNOWS]-(surfer) WHERE js.name = "Johan" AND surfer.hobby = "surfing" RETURN DISTINCT surfer

image

⭐要了解查询的流程, 可在查询之前加 EXPLAIN 或 PROFILE:

explain MATCH (js:Person)-[:KNOWS]-()-[:KNOWS]-(surfer) WHERE js.name = "Johan" AND surfer.hobby = "surfing" RETURN DISTINCT surfer

image

2、查询关系(包含了类型和属性)

match (n:Person)-[r:KNOWS]->(friends) where n.name = "Johan" return r
4.2 复杂查询

image

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命令在图中搜索给定模式,
如果存在,则返回结果
如果它不存在于图中,则它创建新的节点/关系并返回结果