1、图数据库Neo4j介绍
1.1、什么时图数据库(graph database)
当事物存在十分复杂的关系网,传统数据库则很难处理关系运算,图数据库就十分适用于处理庞大的复杂关系网,因此图数据库应运而生。
图数据库是基于图论实现的一种nosql数据库,其数据存储结构和数据查询方式都是以图论为基础的,图数据库主要用于存储更多的连接数据。
图论[Graph Theory]是数学的一个分支。它以图为研究对象,图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。
1.2、什么是Neo4j
neo4j是开源的nosql图形数据库,使用scala和java语言,2007年开始发布
1.3、Neo4j数据模型
图论基础
图是一组节点和连接这些节点的关系,图形以属性的形式将数据存储在节点和关系中,属性是用于表示数据的键值对。在图论中,我们可以用圆圈表示一个节点,节点之间的关系用一个箭头标记表示。
属性图模型
属性图模型规则
- 表示节点,关系和属性中的数据
- 节点和关系都包含属性
- 关系连接节点
- 属性是键值对
- 节点用圆圈表示,关系用方向键表示
- 关系具有方向:单向和双向
- 每个关系包含“开始节点”或“从节点”和“到节点”或“结束节点”
在属性图数据模型中,关系应该是定向的。如果我们尝试创建没有方向的关系,那么它将抛出错误消息。在Neo4j中,关系也应用是有方向性的。如果我们尝试创建没有方向的关系,那么Neo4j会抛出一个错误小徐,“关系应该是方向性的”。
Neo4j图数据库将其所有数据存储在节点和关系中,我们不需要任何额外的RDBMS数据库或Nosql数据库来存储Neo4j数据库数据,它以图的形式存储数据。Neo4j使用本机GPE(图形处理引擎)来使用它的本机图存储格式。
1.4、Neo4j的构建元素
-
节点
节点(Node)是图数据库中的一个基本元素,用来表示一个实体记录,就像关系数据库中的一条记录一样。在Neo4j中节点可以包含多个属性(Property)和多个标签(Label)
- 节点是主要的数据元素
- 节点通过关系连接到其他节点
- 节点可以具有一个或多个属性(即:存储为键/值对的属性)
- 节点有一个或多个标签,用于描述其在图表中的作用
-
属性
属性(Property)是用于描述图节点和关系的键值对。其中Key是一个字符串,值可以通过任何Neo4j数据类型来表示
- 属性是命名值,其中名称(或键)是字符串
- 属性可以被索引或约束
- 可以从多个属性创建符合索引
-
关系
关系(Relationship)同样是图数据库的基本元素。当数据库中已经存在节点后,需要将节点连接起来构成图。关系就是用来连接两个节点,关系也称为图论的边(Edge),其始端和末端都必须是节点,关系不能指向空也不能从空发起。关系和节点一样可以包含多个属性,但关系只能有一个类型(Type)
-
关系连接两个节点
-
关系是方向性的
-
节点可以有多个甚至递归的关系
-
关系可以有一个或多个属性(即存储为键/值对的属性)
基于方向性,Neo4j关系被分为两种主要类型:
-
单向关系
-
双向关系
-
-
标签
标签(Label)将一个公共名称与一组节点或关系相关联,节点或关系可以包含一个或多个标签。我们可以为现有节点或关系创建新标签,我们可以从现有节点或关系中删除标签。
- 标签用于节点分组
- 一个节点可以具有多个标签
- 对标签进行索引以加速在图中查找节点
- 本机标签索引针对速度进行了优化
-
数据浏览器
一旦我们安装了Neo4j,我们就可以访问Neo4j数据浏览器
1.5、使用场景
- 欺诈检测
- 实时推荐引擎
- 知识图谱
- …
2、环境搭建
2.1、安装Neo4jCommunityServer
Windows (zip) Install
-
If it is not already installed, get OpenJDK 8 or Oracle Java 8, recommended for Neo4j 3.0.x Version 7 is recommended for releases prior to 2.3.0.
-
Find the zip file you just downloaded and right-click, extract all.
-
Place the extracted files in a permanent home on your server, for example
D:\neo4j\
. The top level directory is referred to as NEO4J_HOME. -
- To run Neo4j as a console application, use:
<NEO4J_HOME>\bin\neo4j console
- To install Neo4j as a service use:
<NEO4J_HOME>\bin\neo4j install-service
. - For additional commands and to learn about the Windows PowerShell module included in the Zip file, see the Windows installation documentation.
- To run Neo4j as a console application, use:
-
Visit http://localhost:7474 in your web browser.
-
Connect using the username ‘neo4j’ with default password ‘neo4j’. You’ll then be prompted to change the password.
Neo4j Operations Manual: Windows installation →
docker install
- 7474 for HTTP
- 7473 for HTTPS
- 7687 for Bolt.
拉取镜像
docker pull neo4j:3.5.22-community
运行镜像
docker run -d -p 7474:7474 -p 7687:7687 --name neo4j \
-e "NEO4J_AUTH=neo4j/123456" \
-v /usr/local/soft/neo4j/data:/data \
-v /usr/local/soft/neo4j/logs:/logs \
-v /usr/local/soft/neo4j/conf:/var/lib/neo4j/conf \
-v /usr/local/soft/neo4j/import:/var/lib/neo4j/import \
neo4j:3.5.22-community
Start Up the Neo4j Browser
Visit: http://localhost:7474/
Open Neo4j Browser
Once you create a new password for the ‘neo4j’ user upon visiting the Neo4j Browser the first time, you’ll have full access to the Neo4j database.
The Neo4j Browser is a tool for developers to explore their Neo4j database, execute Cypher queries and see results in tabular or graph form. You can even use the Browser to:
- Import data
- Call user-defined procedures in Java
- Profile queries, looking at the execution plan with
EXPLAIN
andPROFILE
.
desktop install
填写相关信息,一键安装
3、Neo4j-CQL使用
3.1、Neo4j-CQL简介
Neo4j的Cypher语言是为处理图形数据而构建的,CQL代表Cypher查询语言。像Oracle数据库具有查询语言SQL,Neo4j具有CQL作为查询语言
- 它是Neo4j图形数据库的查询语言
- 它是一种声明性模式匹配语言
- 它遵循SQL语法
- 它的语法是非常简单且人性化、可读的格式
CQL命令 | 用法 |
---|---|
CREATE 创建 | 创建节点,关系和属性 |
MATCH 匹配 | 检索有关节点,关系和属性数据 |
RETURN 返回 | 返回查询结果 |
WHERE 哪里 | 提供条件过滤检索数据 |
DELETE 删除 | 删除节点和关系 |
REMOVE 移除 | 删除节点和关系的属性 |
ORDER BY以…排序 | 排序检索数据 |
SET 组 | 添加或更新标签 |
使用cypher语言来描述关系:
(fox)<-[:knows]-(周瑜)-[:knows]->(诸葛)-[:knows]->(fox)
3.2、Cypher 简介
Cypher 是一种声明式图形查询语言,允许对图形进行富有表现力和高效的查询和更新。它旨在同时适合开发人员和运营专业人员。Cypher 的设计简单而强大;可以轻松表达高度复杂的数据库查询,使您能够专注于自己的领域,而不会迷失在数据库访问中。
Cypher 受到许多不同方法的启发,并建立在表达查询的既定实践之上。许多关键字,例如WHERE
and ORDER BY
,都受到SQL 的启发。模式匹配借用了SPARQL 的表达式方法。一些列表语义是从 Haskell 和 Python 等语言中借用的。Cypher 的结构基于英语散文和简洁的图像,使查询既易于编写又易于阅读。
快速入门
让我们使用以下查询创建一个简单的示例图:
CREATE (john:Person {name: 'John'})
CREATE (joe:Person {name: 'Joe'})
CREATE (steve:Person {name: 'Steve'})
CREATE (sara:Person {name: 'Sara'})
CREATE (maria:Person {name: 'Maria'})
CREATE (john)-[:FRIEND]->(joe)-[:FRIEND]->(steve)
CREATE (john)-[:FRIEND]->(sara)-[:FRIEND]->(maria)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JzWg9nwu-1646578129157)(https://kroki.io/graphviz/svg/eNqtj8EKgkAQhu89xWAHT0G60iXsVEFREnV0PWztlMK2K6sFYb57q0WUBHbwNMzsfjPfz5OTZmkMKyhAKo4QZjFL0dd4UJpDlt-EadRFcuTRuAcQDCE0BUCwPQrwwSo2qDMl75Kd0fTUXqpYUpuK0jIfoyczmEDgvMiDEkpXZN9F4pGRVU-PSua_X96X5tvFLJhS2dhLOt_r_JERvyM6tYrbuYrbqrLL8dqQIe0Q06zJVAG8zgN4rS5rppNPmfIBKKKtCA==)]
例如,这里有一个查询,它在返回**“John”和找到的任何朋友的朋友之前查找名为“John”和“John’s”的**朋友(尽管不是他的直接朋友)的用户。
MATCH (john {name: 'John'})-[:FRIEND]->()-[:FRIEND]->(fof)
RETURN john.name, fof.name
+----------------------+
| john.name | fof.name |
+----------------------+
| "John" | "Steve" |
| "John" | "Maria" |
+----------------------+
2 rows
接下来,我们将添加过滤以设置更多运动部件:
我们获取用户名列表并从该列表中找到所有具有名称的节点,匹配他们的朋友并仅返回那些具有以**‘S’开头的’name’**属性的关注用户。
MATCH (user)-[:FRIEND]->(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*'
RETURN user.name, follower.name
+---------------------------+
| user.name | follower.name |
+---------------------------+
| "Joe" | "Steve" |
| "John" | "Sara" |
+---------------------------+
2 rows
以下是用于更新图形的子句示例:
CREATE
(和DELETE
):创建(和删除)节点和关系。SET
(和REMOVE
):设置属性值并使用SET
和使用REMOVE
删除它们在节点上添加标签。MERGE
:匹配现有的或创建新的节点和模式。这与唯一约束一起特别有用。
CREATE创建
create语句是创建模型语句用来创建数据模型
创建节点
//创建简单节点
create (n)
//创建多个节点
create (n),(m)
//创建带标签和属性的节点并返回节点
create (n:person {name:'如来'}) return n
//demo
create (:student{name:"小红"}),(:student{name:"张三"}),(:student{name:"小明"})
创建关系
Neo4j图数据库遵循属性图模型来存储和管理其数据。
根据属性图模型,关系应该是定向的。否则,Neo4j将抛出一个错误消息。
基于方向性,Neo4j关系被分为两种主要类型。
- 单向关系
- 双向关系
//使用新节点创建关系
CREATE (n:person {name:'杨戬'})-[r:师傅]->(m:person {name:'玉鼎真人'}) RETURN type(r)
//使用已知节点创建带属性的关系
MATCH (n:person {name:'沙僧'}),(m:person{name:'唐僧'})
CREATE (n)-[r:`师傅`{relation:'师傅'}]->(m) RETURN r
//检索关系节点的详细信息
MATCH(n:person)-[r]-(m:person) RETURN n,m
//demo
match (n:student{name:"小明"}),(m:student{name:"小红"})
create (n)-[r:同学{relation:"同学"}]->(m) return n.name,type(r),m.name
match (n:student),(t:teacher)
create (t)-[r:老师]->(n) return t.name,type(r),n.name
创建全路径
CREATE p=(:person{name:'蛟魔王'})-[:义兄]->(:person{name:'牛魔王'})<-[:义兄]-(:person {name:'鹏魔王'}) RETURN p
MATCH查询
Neo4jCQL match 命令用于
- 从数据库取有关节点和属性的数据
- 从数据库取有关节点,关系和属性的数据
MATCH (n:`西游`) RETURN n LIMIT 25
// 忽略前面n个数据
match (n:student)return n skip 10
RETURN返回
Neo4jCQL return子句用于
- 检索节点的某些属性
- 检索节点的所有属性
- 检索节点和关联关系的某些属性
- 检索节点和关联关系的所有属性
MATCH (n:`西游`) RETURN id(n),n.name,n.tail,n.relation
WHERE子句
像SQL一样,Neo4j CQL在CQL MATCH命令中提供了WHERE子句来过滤MATCH查询的结果
MATCH (n:person) WHERE n.name='孙悟空' or n.name='猪八戒' RETURN n
//创建关系
match (n:person),(m:person) where n.name='孙悟空' and m.name='猪八戒'
create (n)-[r:师弟]->(m) return n.name,type(r),m.name
DELETE删除
Neo4j使用CQL delete子句
- 删除节点
- 删除节点及相关节点和关系
//删除节点(前提:节点不存在关系)
match (n:person{name:"白龙马"}) delete n
//删除关系
match(n:person{name:"沙僧"})<-[r]-(m) delete r return type(r)
//demo
match (n:student{name:"小a"})<-[r]-(m) delete r return type(r)
match (n:student{name:"小艾"})delete n
//删除所有数据
MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r
//删除所有关系和节点
MATCH (n)
DETACH DELETE n
REMOVE删除
create (n:student{name:"小c",age:20,class:"三年二班"})
//删除属性操作
match (n:student{name:"小c"}) remove n.age return n
SET子句
// 设置修改属性值操作,不存在的则新增,存在的则修改
match (n:student{name:"小c"})set n.age=20 return n
ORDER BY排序
Neo4jCQL在MATCH命令中提供了"ORDER BY"子句,对MATCH查询返回的结果进行修改。
我们可以按升序或降序对行进行排序。默认情况下,它按升序对行进行排序。如果我们要按降序对它们进行排序,我们需要使用DESC子句。
//默认升序
match (n:student) return id(n),n.name order by id(n)
//降序
match (n:student) return id(n),n.name order by id(n) desc
UNION子句
与SQL一样,Neo4jCQL有两个子句,将两个不同的结果合并成一组结果
-
UNION
它将两组结果中的公共行组合并返回到一组结果中。它不从两个节点返回重复的行。
限制:
结果列类型和来自两组结果的名称必须匹配,这意味着列名称应该相同,列的数据类型应该相同。
-
UNION ALL
它结合并返回两个结果集的所有行成一个单一的结果集。它还会由两个节点重复行。
限制:
结果列类型,并从两个结果集的名字必须匹配,这意味着列名称应该是相同的,列的数据类型应该是相同的。
MATCH (n:role) RETURN n.name as name UNION
MATCH (m:person) RETURN m.name as name
MATCH (n:role) RETURN n.name as name UNION ALL
MATCH (m:person) RETURN m.name as name
LIMIT和SKIP子句
Neo4jCQL已提供LIMIT子句和SKIP来过滤或限制查询返回的行数。
LIMIT返回前几行,SKIP忽略前几行
//前几行
MATCH (N:`西游`)RETURN n LIMIT 2
//忽略前两行
MATCH(n:person) RETURN n SKIP 2
NULL值
Neo4jCQL将空值视为对节点或关系的属性的缺失值或未定义值。
当我们创建一个具有现有节点标签名称但未指定其属性值的节点时,它将创建一个具有NULL属性值的新节点。
MATCH (n:`西游`) where n.label IS NULL RETURN id(n),n.name,n.tail,n.label
//demo
match (n:student{name:"小a"})set n.sex=null return n
match (n:student)where n.sex is null return n
IN操作符
与SQL一样,Neo4jCQL提供了一个IN运算符,以便为CQL命令提供值的集合。
match (n:student)where n.name in["小红","小明"] return n
INDEX索引
Neo4jSQL支持节点或关系属性上的索引,以提高应用程序的性能。
我们可以为具有相同标签名称的所有节点的属性创建索引。
我们可以在MATCH或WHERE或IN运算符上使用这些索引列来改进CQLCommand的执行。
Neo4j索引操作
- Create Index创建索引
- Drop Index 丢弃索引
// 创建索引
create index on :`西游` (name)
// 删除索引
drop index on :`西游` (name)
//demo
create index on :student (name)
drop index on :student (name)
UNIQUE约束
在Neo4j数据库中,CQL CREATE命令始终创建新的节点或关系,这意味着即使您使用相同的值,它也会插入一个新行。根据我们对某些节点或关系的应用需求,我们必须避免这种重复。
像SQL一样,Neo4j数据库也支持对NODE或Relationship的属性的UNIQUE约束
UNIQUE约束的优点
- 避免重复记录
- 强制执行数据完整性规则
//创建唯一约束-————-所有标签为xiyou的name属性必须是唯一的
create constraint on (n:xiyou) assert n.name is unique
//删除唯一约束
drop constraint on (n:xiyou) assert n.name is unique
DISTINCT
这个函数的用法就像SQL中的distinct关键字,返回的是所有不同值。
match (n:`西游`) return distinct(n.name)
常用函数
- 字符串函数
- AGGREGATION聚合
- 关系函数
字符串函数
与SQL一样,Neo4J CQL提供了一组String函数,用于在CQL查询中获取所需的结果。
这里我们将讨论一些重要的和经常使用的功能。
功能 | 描述 |
---|---|
UPPER | 它用于将所有字母更改为大写字母。 |
LOWER | 它用于将所有字母改为小写字母。 |
SUBSTRING | 它用于获取给定String的子字符串。 |
REPLACE | 它用于替换一个字符串的子字符串。 |
UPPER
它需要一个字符串作为输入并转换为大写字母。 所有CQL函数应使用“()”括号。
函数语法
UPPER (<input-string>)
MATCH (e:Employee)
RETURN e.id,UPPER(e.name),e.sal,e.deptno
LOWER
它需要一个字符串作为输入并转换为小写字母。 所有CQL函数应使用“()”括号。
函数语法
LOWER (<input-string>)
MATCH (e:Employee)
RETURN e.id,LOWER(e.name),e.sal,e.deptno
SUBSTRING
它接受一个字符串作为输入和两个索引:一个是索引的开始,另一个是索引的结束,并返回从StartInded到EndIndex-1的子字符串。 所有CQL函数应使用“()”括号。
函数语法
SUBSTRING(<input-string>,<startIndex> ,<endIndex>)
注意:-
在Neo4J CQL中,如果一个字符串包含n个字母,则它的长度为n,索引从0开始,到n-1结束。
是SUBSTRING函数的索引值。
是可选的。 如果我们省略它,那么它返回给定字符串的子串从startIndex到字符串的结尾。
MATCH (e:Employee)
RETURN e.id,SUBSTRING(e.name,0,2),e.sal,e.deptno
//demo
match (n:student)where n.name="小明"return substring(n.name,1,1)
AGGREGATION聚合
和SQL一样,Neo4j CQL提供了一些在RETURN子句中使用的聚合函数。 它类似于SQL中的GROUP BY子句。我们可以使用MATCH命令中的RETURN +聚合函数来处理一组节点并返回一些聚合值。
聚集功能 | 描述 |
---|---|
COUNT | 它返回由MATCH命令返回的行数。 |
MAX | 它从MATCH命令返回的一组行返回最大值。 |
MIN | 它返回由MATCH命令返回的一组行的最小值。 |
SUM | 它返回由MATCH命令返回的所有行的求和值。 |
AVG | 它返回由MATCH命令返回的所有行的平均值。 |
COUNT
它从MATCH子句获取结果,并计算结果中出现的行数,并返回该计数值。 所有CQL函数应使用“()”括号。
函数语法
COUNT(<value>)
// 此示例演示如何使用COUNT(*)函数返回数据库中可用的Employee节点数。
MATCH (e:Employee) RETURN COUNT(*)
// demo
match (n:student)return count(n)
MAX
它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找最大值。
函数语法
MAX(<property-name> )
MIN
它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找最小值。
函数语法
MIN(<property-name> )
注意 -
应该是节点或关系的名称。让我们用一个例子看看MAX和MIN的功能。
MATCH (e:Employee)
RETURN MAX(e.sal),MIN(e.sal)
AVG
它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找平均值。
函数的语法
AVG(<property-name> )
SUM
它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找求和值。
函数的语法
SUM(<property-name> )
MATCH (e:Employee)
RETURN SUM(e.sal),AVG(e.sal)
关系函数
Neo4j CQL提供了一组关系函数,以在获取开始节点,结束节点等细节时知道关系的细节。在这里,我们将讨论一些重要的和经常使用的功能。
功能 | 描述 |
---|---|
STARTNODE | 它用于知道关系的开始节点。 |
ENDNODE | 它用于知道关系的结束节点。 |
ID | 它用于知道关系的ID。 |
TYPE | 它用于知道字符串表示中的一个关系的TYPE。 |
STARTNODE和ENDNODE
它需要一个字符串作为输入并为大写格式, 所有CQL函数应使用“()”括号。
函数语法
STARTNODE (<relationship-label-name>)
ENDNODE (<relationship-label-name>)
此示例演示如何使用CQL STARTNODE关系函数来检索关系的开始节点详细信息。
在关系“ACTION_MOVIES”上执行STARTNODE()函数之前,我们将检查其详细信息
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN STARTNODE(movie)
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN ENDNODE(movie)
ID和TYPE
ID和TYPE关系函数来检索关系的Id和类型详细信息。
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN ID(movie),TYPE(movie)
demo1 ID和TYPE关系函数来检索关系的Id和类型详细信息。
MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2)
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN STARTNODE(movie)
demo2 使用CQL ENDNODE关系函数来检索关系的结束节点详细信息。
MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2)
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN ENDNODE(movie)
demo3 使用CQL ID和TYPE关系函数来检索关系的Id和类型详细信息。
MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2)
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN ID(movie),TYPE(movie)
)-[movie:ACTION_MOVIES]->(b)
RETURN ID(movie),TYPE(movie)
> demo1 ID和TYPE关系函数来检索关系的Id和类型详细信息。
```cypher
MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2)
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN STARTNODE(movie)
demo2 使用CQL ENDNODE关系函数来检索关系的结束节点详细信息。
MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2)
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN ENDNODE(movie)
demo3 使用CQL ID和TYPE关系函数来检索关系的Id和类型详细信息。
MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2)
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b)
RETURN ID(movie),TYPE(movie)