图数据库neo4j学习

在日常运维开发过程中,可能遇到需要存储或者展示依赖关系的情况,这种比较适合用图数据库去存储。

生产上大体量的话可以使用Nebula Graph ,如果数据量比较小也可以使用单机的neo4j。

下面开始neo4j的基本知识的学习。

CREATE创建节点

简单的写法

代码语言:txt复制
create (:student{name:'zhangsan',age:22}),(:student{name:'lisi',age:21}) 
 
如果要带返回的,可以使用下面的写法
create (nn:student{name:'zhangsan',age:22}),(mm:student{name:'lisi',age:21}) return nn,mm

插入一条带name的点(括号中的是这个点的属性)

代码语言:txt复制
create (n:SRE {name:'zhangsan',sex:'Male', age: 23, job:'dba'})

插入一条不带name的点

代码语言:txt复制
create (n:SRE {sex:'Male', age: 23, job:'dba',first_name:'li',last_name:'rulei'})
match (n:SRE) return n

然后执行查询,可以看到create的时候如果不带name的话,查询出来的name是空的(另一个是上一步插入的带name的点)

插入一条带多个label的点

代码语言:txt复制
create (n:SRE:DBA:SA:SB {name:'aaaaaa'})

然后执行查询

对于有依赖关系的点,直接删除会有报错提示

对于这种情况下,有2种方法:

1、先detach移除关系后,还可以删除节点【DETACH DELETE 语句的作用就是在删除节点之前,先自动断开该节点与其他节点之间的所有关系,然后再将该节点从数据库中删除】

代码语言:txt复制
MATCH (n:shen1 {name:'杨戬'}) DETACH DELETE n;

MATCH (n:shen2 {name:'玉鼎真人'}) DETACH DELETE n;

2、找到需要移除的关系,先移除关系,然后再执行delete操作

代码语言:txt复制
-- 先删除relation关系
MATCH (n1:shen1 {name:'杨戬'})-[r:RELATED_TO]->(n2:shen2 {name:'玉鼎真人'})
DELETE r;

--再删除点
MATCH (n:shen1 {name:'杨戬'}) DELETE n;

CREATE创建关系

先使用create创建节点,然后使用match创建关系

代码语言:txt复制
create (n:shen1 {name:'杨戬',age:333})
create (n:shen2 {name:'玉鼎真人',age:999})
MATCH (n1:shen1 {name:'杨戬'}), (n2:shen2 {name:'玉鼎真人'}) 
CREATE (n1)-[r:RELATED_TO]->(n2)
RETURN n1, r, n2;

上面的命令,可以使用下面的写法,一条cql就完成创建新节点并创建关系

代码语言:txt复制
create (n:Person {name:'杨戬',age:333}) -[r:师傅]->(m:Person {name:'玉鼎真人',age:999}) return *

如果只返回类型,可以使用type函数,例如:

代码语言:txt复制
 create (n:Person {name:'杨戬'}) -[r:师傅]->(m:Person {name:'玉鼎真人'}) 
 return type(r)

使用已知节点创建带属性的关系

代码语言:txt复制
match (n:Person {name:'沙僧'}), (m:Person {name:'唐僧'})
create (n) -[r:`师傅`{relation:'师傅'}]->(m) return r

MATCH查询节点间的关系

模糊查询,不带任何条件

代码语言:txt复制
match p = () -[r] -> ()  return p limit 2

检索关系节点的详细信息

代码语言:txt复制
match (n:Person)-[r]-(m:Person) return n,m
match(n:Person{name:'杨戬'}),(m:Person {name:'玉鼎真人'}) return n,m

查询特定类型关系的节点对

代码语言:txt复制
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie)
RETURN p, r, m;

查询特定节点间的特定关系

代码语言:txt复制
MATCH (p:Person {name: 'Tom Hanks'})-[r:ACTED_IN]->(m:Movie {title: 'Forrest Gump'})
RETURN p, r, m;

查询节点间的所有关系【常用】

代码语言:txt复制
MATCH (n1:shen1 {name:'杨戬'})-[r]-(n2:shen2 {name:'玉鼎真人'})
RETURN n1, r, n2;

查询具有特定属性的关系

代码语言:txt复制
MATCH (p:Person)-[r:ACTED_IN {role: 'Forrest Gump'}]->(m:Movie)
RETURN p, r, m;

使用limit限制返回的记录数

代码语言:txt复制
match (n:CTO {name:'zhangsan',job:'dba'}) return n.name,id(n) limit 1

条件查询(查询标签为SRE,且属性当中的name为zhangsan的点)

代码语言:txt复制
match (n:CTO {name:'zhangsan',job:'dba'}) return n.name,n.job,id(n) 或者用where条件的写法 match (n:CTO ) where n.name='zhangsan' and n.job='dba' return n.name,id(n)

复杂写法

代码语言:txt复制
match(n:Person {name:'杨戬'}), (m: xiyouRelation) where m.from = '孙悟空'
return n.name,m.relation,m.to
match(n:Person {name:'杨戬'}), (m: xiyouRelation) where m.from = n.name
return n.*,m.*

移除关系

1 基于关系类型和节点属性移除关系

代码语言:txt复制
MATCH (n1:class1 {name:'杨戬'})-[r:RELATED_TO]->(n2:class2 {name:'杨戬'})
DELETE r;

或 match (n:Person) -[r:`师傅`] -> (m:Person) where n.name='杨戬'  
delete r

2 移除两个节点间的所有关系

代码语言:txt复制
MATCH (n1:shen1 {name:'杨戬'})-[r]->(n2:shen2 {name:'玉鼎真人'})
DELETE r;

创建全路径

复杂写法,创建的时候使用return返回结果

代码语言:txt复制
create p =(:Person{name:'蛟魔王'}) -[:义兄]->(:Person{name:'牛魔王'}) <-[:义兄]-(:Person {name:'鹏魔王'}) 
return p

REMOVE移除属性

代码语言:txt复制
移除符合记录的age属性
MATCH (n:shen2) remove n.age return n;

移除符合记录的address属性
MATCH (n:shen2{address: "tianshang"}) remove n.address  return n

移除pic和png属性
create(m:Movie:pic:png:jpeg {name:'cncf', type:'cloud_native'})
MATCH (m:Movie:pic:png) REMOVE m:pic:png return m

SET子句

对现有的节点或者关系添加新的属性。包括:

1、向现有的节点或者关系添加新的属性

2、添加或者更新属性值

使用set添加或者修改节点的属性

创建测试的节点

代码语言:txt复制
create(m:Movie:pic:png:jpeg {name:'cncf', type:'cloud_native'})
MATCH (m:Movie) return m

添加属性

代码语言:txt复制
MATCH(m:Movie {name:'cncf'}) set m.scope='cloud native' return m

更新原有的属性的值

代码语言:txt复制
MATCH(m:Movie {name:'cncf'}) set m.scope='just a update test' 
return m

使用set添加或者修改关系中的属性

为关系添加新属性

代码语言:txt复制
MATCH (p1:Person)-[r:FRIEND]->(p2:Person)
SET r.since = '2020-01-01'
RETURN r;

修改关系的现有属性

代码语言:txt复制
MATCH (p1:Person)-[r:FRIEND]->(p2:Person)
SET r.since = '2021-01-01'
RETURN r;

同时添加或修改多个属性

代码语言:txt复制
MATCH (p1:Person)-[r:FRIEND]->(p2:Person)
SET r.since = '2022-01-01', r.intimacy = 80
RETURN r;

ORDER BY排序

使用起来很简单

代码语言:txt复制
match(n:Person) return id(n),n.name order by id(n)

match(n:Person) return id(n),n.name order by id(n) desc

match(n:Person) return id(n),n.name order by n.name desc

UNION子句

UNION:用于合并多个查询的结果集,会自动去除重复的行。

UNION ALL:同样用于合并多个查询的结果集,但不会去除重复的行,会保留所有结果。

注意事项:

列的一致性:使用 UNION 或 UNION ALL 时,每个查询的返回列的数量和类型必须一致。例如,如果第一个查询返回 name 和 age 两列,那么第二个查询也必须返回两列,且数据类型要兼容。

性能考虑:UNION ALL 的性能通常比 UNION 要好,因为 UNION 需要额外的操作来去除重复的行。如果确定结果集中不会有重复的行,或者不需要去除重复行,建议使用 UNION ALL。

create (n:Person {name:'zhangsan',age:45,sex:'M',job:'sa'});

create (n:Person {name:'zhangsan',age:45,sex:'M'});

create (n:Person {name:'zhangsan',age:22,sex:'F'});

create (n:Person {name:'lisi',age:22,sex:'F'});

create (n:Person {name:'lisi',age:36,sex:'M'});

UNION去除重复行

代码语言:txt复制
MATCH (p:Person)
WHERE p.age < 30
RETURN p.name 
UNION
MATCH (p:Person)
WHERE p.age > 40
RETURN p.name;

UNION ALL 保留所有行

代码语言:txt复制
MATCH (p:Person)
WHERE p.age < 30
RETURN p.name 
UNION ALL
MATCH (p:Person)
WHERE p.age > 40
RETURN p.name;

LIMIT和SKIP子句

Limit限制返回的记录数

Skip忽略前N行

例子:

代码语言:txt复制
match (n:Person) return n.name,id(n) order by id(n) desc limit 2

match (n:Person) return n.name,id(n) order by id(n) desc skip 3 limit 2

NULL值

CQL将空值视为对节点或者关系的属性的缺失值或者未定义值。

IN操作符

代码语言:txt复制
match (n:Person)  where n.name in ['zhangsan','lisi'] 
return n.name,n.age,id(n)

INDEX索引

为节点创建索引

代码语言:txt复制
CREATE [RANGE] INDEX [index_name] [IF NOT EXISTS]
FOR (n:LabelName)
ON (n.propertyName_1[,
    n.propertyName_2,
    ...
n.propertyName_n])

常用: CREATE INDEX FOR (p:Person) ON (p.name);

为关系创建索引

语法:

代码语言:txt复制
CREATE [RANGE] INDEX [index_name] [IF NOT EXISTS]
FOR ()-”[“r:TYPE_NAME”]”-()
ON (r.propertyName_1[,
    r.propertyName_2,
    ...
r.propertyName_n])

常用: CREATE INDEX FOR ()-[r:FRIEND]-() ON (r.since);

UNIQUE约束

/

创建唯一约束

代码语言:txt复制
点:
CREATE CONSTRAINT book_isbn FOR (book:Book) REQUIRE book.isbn IS UNIQUE
CREATE CONSTRAINT book_title_year FOR (book:Book) REQUIRE (book.title, book.publicationYear) IS UNIQUE

关系:
CREATE CONSTRAINT sequels FOR ()-[sequel:SEQUEL_OF]-() REQUIRE sequel.order IS UNIQUE
CREATE CONSTRAINT prequels FOR ()-[prequel:PREQUEL_OF]-() REQUIRE (prequel.order, prequel.author) IS UNIQUE

插入测试(多次执行会报错提示重复):
CREATE (book:Book {isbn: '1449356265', title: 'Graph Databases'})
CREATE (:Book {title: 'Spirit Walker'})-[:SEQUEL_OF {order: 1, seriesTitle: 'Chronicles of Ancient Darkness'}]->(:Book {title: 'Wolf Brother'})

删除约束

需要先查出来,然后再执行删除操作

代码语言:txt复制
show all indexes;

drop constraint  book_isbn;

drop constraint sequels;

查看和删除索引

/

查看索引

代码语言:txt复制
SHOW [ALL | FULLTEXT | LOOKUP | POINT | RANGE | TEXT | VECTOR] INDEX[ES]

常用 SHOW INDEXES;

删除索引

删除普通索引和唯一索引都需要先用show indexes列出索引,然后再执行drop index操作。

代码语言:txt复制
drop index index_4b2e9408 if exists

DISTINCT去重

代码语言:txt复制
match (n:Person ) return distinct(n.name)

match (n:Person ) return distinct(id(n))

常用函数

/

【重点】

【重点】

监控

/

数据的备份和恢复

/

/

目前只能停机后进行备份

代码语言:txt复制
export JAVA_HOME=/usr/local/software/jdk-22.0.1
cd /usr/local/software/neo4j_5.26.3
./bin/neo4j stop
mkdir abcd
./bin/neo4j-admin database dump neo4j  --to-path=./abcd