锅炉信息网 > 锅炉知识 > 锅炉百科

neo4j图数据库

发布时间:

前言:NoSQL数据库四大家族 列存储 Hbase,键值(Key-Value)存储 Redis,图像存储 Neo4j,文档存储 MongoDB一、简介1.1 什么是neo4jNe

前言:NoSQL数据库四大家族 列存储 Hbase,键值(Key-Value)存储 Redis,图像存储 Neo4j,文档存储 MongoDB

一、简介

1.1 什么是neo4j

Neo4j是以原生图形数据库为核心,以更自然的连接状态存储和管理数据。 是用 Java 和 Scala 编写的,源代码可在GitHub上找到。

图数据库采用属性图方式,对遍历性能和操作运行时间都有好处。

1.1.1 什么是图数据库

图数据库是使用图数据结构存储数据,图数据结构由可以通过关系连接的节点组成,如下图


image


Neo4j 属性图数据库模型包括: - 节点描述域的实体(离散对象)。 - 节点可以有零个或多个标签来定义(分类)它们是什么类型的节点。 - 关系描述了源节点和目标节点之间的连接。 - 关系总是有一个方向(一个方向)。 - 关系必须有一个类型(一种类型)来定义(分类)它们是什么类型的关系。 - 节点和关系可以具有进一步描述它们的属性(键值对)


image


我们可以从上图来认识下图数据库模型 - 节点:三个方框 - 标签:方框上半部分 - 节点属性:方框下半部分 - 关系:虚线和实线 - 关系类型:ACTED_IN和DIRECTED - 关系属性:roles=['Forrest']

1.2 neo4j历史

Neo4j 最初是作为嵌入式 Java 数据库创建的;这就是名称中的“4j”的来源。Neo4j 最初创建是为了解决创始人在构建内容管理系统 (CMS) 时遇到的一些问题,特别是围绕照片使用的一些权利和元数据。他们发现由于所有不同的连接和关系以及数据的丰富性,很难在关系数据库中表示。所以这就是 Neo4j 最初被创建的原因。

创始人也很快意识到,除了 CMS 应用程序中的这个嵌入式数据库之外,还有许多其他有趣的用例。所以 Neo4j 很快演变成一个更通用的系统迅速被使用在个性化推荐,以及处理物流和路线、网络拓扑图等地方.

1.3为什么要使用neo4j

我们生活在一个互联的世界中,无论是社交网络、支付网络还是道路网络,您都会发现一切都是相互关联的关系图

传统数据库数据格式很难处理数据之前的关联关系,就算有主键关联,随着深度加深难度指数上升,而因为neo4j使用的是图数据库的方式存储,意味着我们不需要使用特殊属性(例如外键)或带外处理(例如 map-reduce)来推断实体之间的连接。通过将节点和关系组装成连接的结构,图数据库使我们能够构建简单而复杂的模型,这些模型紧密地映射到我们的问题域。

在neo4j官网中有一份测评报告,查找用户好友及好友的好友,包含100万数据的,mysql及neo4j效率对比如下

层级Execution Time – MySQLExecution Time–Neo4j
20.0160.010
330.2670.168
41,543.5051.359
5Not Finished in 1 Hour2.132

上述结果可以看出简单的好友查询neo4j比mysql快60%,查朋友的朋友时,neo4j效率比mysql高180倍,深度为3时,neo4j效率比mysql高1135倍,深度为五时mysql超时

二、neo4j安装

1、官网下载合适版本,下载链接 4.0版本以上就需要jdk11支持了

2、解压安装包

3、bin目录下打开cmd

4、neo4j.bat install-service安装neo4j服务

5、neo4j.bat start启动

6、使用浏览器neo4j http://127.0.0.1:7474/

默认的账号是 neo4j 密码 neo4j 这里第一次登录的话会要求修改密码

至此我们就可以正常使用neo4j了

我们在使用过程中需要学习Cypher图形查询语言

三、cypher语言学习

3.1 什么是Cypher语言

Cypher 是一种声明式图查询语言,允许对图进行富有表现力和高效的查询、更新和管理。由于它与其他语言的相似性和直观性,它是迄今为止最容易学习的图形语言。

3.2 学习Cypher语言

3.2.1 cypher语法介绍

我们已经知道cypher是用来查询neo4j图数据中的数据,所以我们可以结合一个图数据来认识cypher语法


image


从上图按照我们学习的neo4j基础概念可以知道以下信息:

sally喜欢图表技术,和John是朋友,为Neo4j工作

我们通过基础概念学习已经知道图数据是包括:节点(节点标签、节点属性)、关系(关系类型、关系属性),我们接下来就需要使用Cypher将这些表示出来

1. 节点表示

Cypher 中的节点,是使用括号将节点括起来,例如(node),括号看起来与可视化表示用于我们数据模型中节点的圆圈的相似之处。节点的任何信息都可以卸载括里面包括:节点变量、节点标签、节点属性

  • 节点变量 如果我们查询到一个节点,然后想在查询后返回节点,我们就需要定义一个变量,就如果我们在java调数据库查到数据需要对象接收一样,如果不定义就无法在后续使用数据
  • 节点标签 上述图中我们可以看到每个节点都有标签,如果我们想筛选指定标签的数据或给节点创建标签,我们可以指定节点标签,如图中的Person,Technology、 和Company
  • 节点属性 如图中的节点属性,如果我们想要按照属性筛选或给节点创建属性,可以指定属性

示例:

(p:Person {name: 'Sally'})n(:Person {name: 'Sally'})

p为变量,Person为标签,{name: 'Sally'}为属性

2. 关系表示

为了充分利用图数据库的功能,我们还需要表达节点之间的关系。关系在 Cypher 中使用箭头-->或<--两个节点之间表示,语法看起来像在表示中连接我们的节点的箭头和线。无向关系表示为没有箭头,只有两个破折号--,虽然插入必须有方向,但是在查询的时候如果不知道方向也是可以不指定,这意味着可以在任一方向上遍历关系

有关关系的信息,我们可以使用【】中括号编写,有关关系的任何信息都可以写在中括号中,如下述示例

(p:Person)-[rel:LIKES {type:'Graphs'}]->(t:Technology) n(p:Person)<-[rel:LIKES {type: 'Graphs'}]-(t:Technology) n(p:Person)-[rel:LIKES {type: 'Graphs'}]-(t:Technology)

我们也可以将一个sql赋值一个变量,可以在语句其他地方使用

sql = (p:Person)-[rel:LIKES {type: 'Graphs'}]->(t:Technology)

3.2.2 Cypher语法实践

我们已经知道如何通过Cypher表示图数据中的节点、关系、属性等信息,但是缺少一些关键字来告诉我们是要做什么动作,比如创建还是查询,见下列表格

S.NoCypher关键字作用
1CREATE 创建创建节点,关系和属性
2MATCH 匹配检索有关节点,关系和属性数据
3RETURN 返回返回查询结果
4WHERE 条件提供条件过滤检索MATCH数据
5DELETE 删除删除节点和关系
6REMOVE 移除删除节点和关系的属性
7SET 设置添加或更新标签
8ORDER BY 排序对结果排序
9SKIP LIMIT 分页分页
10DISTINCT 排重排重

接下来我们要使用这些关键字和我们学习的基础语法在neo4j中进行增删改查

创建操作

创建节点

#创建单个节点nCREATE (n)n#创建多个节点nCREATE (n), (m)n#创建带有单个标签的节点nCREATE (n:Person)n#创建带有多个标签的节点nCREATE (n:Person:Swedish)n#创建带有标签和属性的节点并返回nCREATE (n:Person {name: 'Andy', title: 'Developer'}) return n.name,n.titlen#创建一个电影节点nCREATE (m:Movie {title:'测试电影'})

创建关系

#创建已知节点创建关系,并设置属性nmatch (p:Person),(m:Movie)nwhere p.name = 'Andy' and p.title = 'Developer' and m.title = '测试电影'ncreate (p)-[r:ACTED_IN {year:1980}]->(m)nreturn p,r,mn#创建新的节点并创建关系ncreate (p:Person {name:"Jry"})-[r:WORK_FOR]->(m:michael{name:'Mich'})nreturn p,r,m

创建完整链路

#创建完整链路ncreate p = (Person {name:"Tom"})-[:WORK_FOR]->(michael{name:'Michael'})nreturn p

MERGE操作

MERGE操作会先进行查询如果未查询到会进行新建操作

#新建一个张三节点nmerge (p:Person {name:'张三'})nreturn pn#还是新建张三并进行属性匹配,由于属性不完全匹配还是新增操作,可以看到id不同nmerge (p:Person {name:'张三',height:185})nreturn pn#匹配存在的节点nmerge (p:Person {name:'张三',height:185})nreturn pn#以现有节点属性去匹配新增节点nMATCH (person:Person)MERGE (city:City {name: person.bornIn})nRETURN person.name, person.bornIn, cityn#创建节点时设置额外属性nMERGE (keanu:Person {name: '李四'})nON CREATEn SET keanu.created = timestamp()nRETURN keanu.name, keanu.createdn#找到节点时设置额外属性nMERGE (person:Person {name:'张三'})nON MATCHn SET person.found = truenRETURN person.name, person.foundn#ON CREATE/ON MATCH可以一起使用n#关系不存在创建关系nMATCHn (charlie:Person {name: '张三'}),n (wallStreet:Movie {title: '测试电影'})nMERGE (charlie)-[r:ACTED_IN]->(wallStreet)nRETURN charlie.name, type(r), wallStreet.title

更多merge操作参考官方文档

SET操作

set操作可以用来做更新操作

新增属性

#设置属性nMATCH (n {name: '张三'})nSET n.surname = '胖墩'nRETURN n.name, n.surnamen#使用case-when设置属性nMATCH (n {name: '张三'})nSET (CASE WHEN n.height = 185 THEN n END).worksIn = '工厂'nRETURN n.name, n.worksIn

更新属性

MATCH (n {name: '张三'})nSET n.height = toString(n.height)nRETURN n.name, n.height

删除属性

#删除单个属性nMATCH (n {name: '张三'})nSET n.height = nullnRETURN n.name, n.heightn#删除所有属性nMATCH (p {name: 'Jry'})nSET p = {}nRETURN p.name

DELETE操作

delete可以进行删除节点操作,前提是需要将节点上的关系清除

MATCH (n:Person {name: '李四'})nDELETE nn#当数据量不大,我们想清除所有数据nMATCH (n)nDETACH DELETE nn#删除节点及所有关系nMATCH (n {name: 'Andy'})nDETACH DELETE nn#只删除关系nMATCH (n {name: 'Tom'})-[r:KNOWS]->()nDELETE r

REMOVE操作

remove主要用来删除属性和标签

Neo4j 不允许存储null在属性中。相反,如果不存在值,则该属性不存在

#删除属性nMATCH (a {name: '张三'})nREMOVE a.heightnRETURN a.name, a.heightn#删除标签nMATCH (n {name: 'Tom'})nREMOVE n:PersonnRETURN n.name, labels(n)n#删除多个标签nMATCH (n {name: 'Tom'})nREMOVE n:Person:MovienRETURN n.name, labels(n)

MATCH查询操作

要进行查询操作,我们首先初始化一批数据

在安装完成neo4j后,可以直接使用 http://127.0.0.1:7474/页面中的示例数据来初始化数据


image


执行后得到下面结果:


image


我们基于这些数据进行后续的查询操作

节点查询

#查询所有节点nMATCH (n)nRETURN nn#根据标签查询nmatch (m:Movie)nreturn mn#和Lana Wachowski相关的数据 --表示相关,无视关系类型和方向nMATCH (director {name: 'Lana Wachowski'})--(movie)nRETURN movie.title

关系查询

#查看和Lana Wachowski属于》关系的数据nMATCH (:Person {name: 'Lana Wachowski'})-->(movie)nRETURN movie.titlen#关系匹配nMATCH (wallstreet:Movie {title: 'A Few Good Men'})<-[r:ACTED_IN]-(actor)nRETURN actor.name,rn#多关系匹配nMATCH (wallstreet:Movie {title: 'A Few Good Men'})<-[:ACTED_IN|DIRECTED]-(actor)nRETURN actor.namen#多重关系匹配nmatch (p:Person {name:'Keanu Reeves'})-[r:ACTED_IN]->(m:Movie)<-[r1:DIRECTED]-(director:Person)nreturn m.title, director.namen#可变长度关系匹配n#如下查看和Keanu Reeves相关的ACTED_IN关系节点,路径长度为1-3nmatch (p:Person {name:'Keanu Reeves'})-[r:ACTED_IN*1..3]->(m:Movie)nreturn m

最短路径

#查看两人节点数不超过15个的最短路径nmatch n(p:Person {name:'Keanu Reeves'}),n(p1:Person {name:'Lilly Wachowski'}),ns = shortestPath((p)-[*..15]-(p1))nreturn sn#路径过滤,查找路径时不考虑PRODUCED关系nmatch n(p:Person {name:'Keanu Reeves'}),n(p1:Person {name:'Lilly Wachowski'}),ns = shortestPath((p)-[*..10]-(p1))nWHERE none(r IN relationships(s) WHERE type(r) = 'PRODUCED')nreturn s

ID查找

#id查找nMATCH (n)nWHERE id(n) = 0nRETURN nn#关系id查找nMATCH (a)-[r]-(b)nWHERE id(r) = 0nRETURN a, bn#多ID匹配nMATCH (n)nWHERE id(n) IN [0, 3, 5]nRETURN n

3.2.3cypher高级功能

字符串函数

left函数

left函数相当于从左侧开始截取字符串

RETURN left('hello', 3)

Right函数

right函数相当于从右侧开始截取字符串

RETURN right('hello', 3)

ITrim函数

ITrim函数主要去除前导空格

RETURN lTrim(' hello')n#返回'hello'

rTrim函数

ITrim函数主要去除后导空格

RETURN rTrim('hello ')n#返回'hello'

replace函数

replace函数替换目标字符串

RETURN replace("hello", "l", "w")n#返回"hewwo"

split函数

split函数指定符号拆分字符串

RETURN split('one,two', ',')n#返回["one","two"]

更多字符串函数参考https://neo4j.com/docs/cypher-manual/current/functions/string/

聚合函数

avg函数

该函数avg()返回一组数值的平均值

MATCH (n:Person)nRETURN avg(n.born)

collect函数

该函数collect()返回一个聚合列表,其中包含表达式返回的值。任何null值都将被忽略,并且不会添加到列表中。

MATCH (n:Person)nRETURN collect(n.born)

count函数

该函数count(*)可用于返回节点数

#节点求数量nMATCH (n {name: 'Keanu Reeves'})-->(x)nRETURN labels(n), n.born, count(*)n#关系分组求数量nMATCH (n {name: 'Keanu Reeves'})-[r]->(x)nRETURN type(r), count(*)

max/min函数

该函数max/min返回一组值中的最大/小值。字符串默认低于0

#最大nUNWIND [1, 'a', null, 0.2, 'b', '1', '99'] AS valnRETURN max(val)n#最小nUNWIND [1, 'a', null, 0.2, 'b', '1', '99'] AS valnRETURN min(val)

更多聚合函数参考https://neo4j.com/docs/cypher-manual/current/functions/aggregating/#functions-max

shortestPath 函数

返回最短路径

MATCH p=shortestPath((person:Person {name:"Keanu Reeves"})-[*]-(person2:Personn{name:"Lilly Wachowski"}) ) RETURN length(p), nodes(p)

四、事务

为了保持数据的完整性和保证良好的事务行为,Neo4j也支持ACID特性 。

注意:

(1)所有对Neo4j数据库的数据修改操作都必须封装在事务里。
(2)默认的isolation level是READ_COMMITTED
(3)死锁保护已经内置到核心事务管理 。 (Neo4j会在死锁发生之前检测死锁并抛出异常。在异常抛出之前,事务会被标志为回滚。当事务结束时,事务会释放它所持有的锁,则该事务的锁所引起的死锁也就是解除,其他事务就可以继续执行。当用户需要时,抛出异常的事务可以尝试重新执行)
(4)除特别说明,Neo4j的API的操作都是线程安全的,Neo4j数据库的操作也就没有必要使用外部的同步方法。

五、索引

Neo4j CQL支持节点或关系属性上的索引,以提高应用程序的性能。

可以为具有相同标签名称的属性上创建索引。

可以在MATCH或WHERE等运算符上使用这些索引列来改进CQL 的执行

创建索引

#创建节点单一属性索引nCREATE INDEX ON:Person (name)n#创建复合索引nCREATE INDEX ON:Person (name,born)

查看索引

call db.indexes

删除索引

DROP INDEX ON :Person(name)

六、约束

作用 - 避免重复记录。 - 强制执行数据完整性规则

唯一节点属性约束

唯一属性约束确保属性值对于具有特定标签的所有节点都是唯一的。对于多个属性的唯一属性约束,属性值的组合是唯一的。

唯一约束不要求所有节点都具有列出的属性的唯一值——没有对应属性的节点不受此规则的约束

#创建唯一节点属性约束nCREATE CONSTRAINT ON (person:Person) ASSERT person.name IS UNIQUEn#删除唯一节点属性约束nDROP CONSTRAINT ON (cc:Person) ASSERT cc.name IS UNIQUn#查看约束ncall db.constraints

六、Spring boot整合neo4j

1、增加依赖

<dependency>n <groupId>org.springframework.boot</groupId>n <artifactId>spring-boot-starter-data-neo4j</artifactId>n</dependency>n<dependency>n <groupId>org.neo4j</groupId>n <artifactId>neo4j-ogm-bolt-driver</artifactId>n</dependency>

2、增加配置

spring:n data:n neo4j:n username: neo4jn password: 123456n uri: bolt://127.0.0.1:7687

3、增加节点实例

@NodeEntityn@Datanpublic class Person implements Serializable {n @Idn @GeneratedValuen private Long id;n @Property("cid")n private int pid;n @Propertyn private String name;n @Relationship(type = "Friends",direction = Relationship.INCOMING)n private Set<Person> relationPersons;n}

4、增加dao类

@Repositorynpublic interface PersonDao extends Neo4jRepository<Person,Long> {n @Query("match(p:Person) where p.born > {0} return p")n List<Person> personList(Integer born);n @Query("MATCH p=shortestPath((person:Person {name:{0}})-[*1..4]- (person2:Person {name:{1}}) ) RETURN p")n List<Person> shortestPath(String startName,String endName);n}

5、增加服务类

@Servicenpublic class PersonService {n @Autowiredn private PersonDao personDao;nn public List<Person> personList(Integer born){n return personDao.personList(born);n }n public Person save(Person person){n return personDao.save(person);n }nn public List<Person> shortestPath(String startName, String endName){n return personDao.shortestPath(startName,endName);n }n}

6、测试类

@SpringBootApplicationnpublic class Neo4jSpringbootDemoApplication {nn public static void main(String[] args) {n ApplicationContext app =n SpringApplication.run(Neo4jSpringbootDemoApplication.class,args);n PersonService personService =n app.getBean(PersonService.class);n List<Person> datas = personService.personList(1980);n System.out.println(datas);n System.out.println(personService.shortestPath("Bill Pullman","Tom Hanks"));n }nn}

以上内容就是neo4j的基础概念和基础使用

neo4j的官方文档内容非常详细,大家想深入了解可以官网查看

大家有更好的观点可以评论或私信讨论

精选推荐

  • 711关东煮供应商
    711关东煮供应商

    今天给大家介绍三位,奶粉,全家、罗森这些便利店里关东煮的供应商。店里卖三四块钱一串的关东煮,在网上买不到,一块钱就搞定。首先关东

  • 健康日历|高压锅容易爆炸的4个原因
    健康日历|高压锅容易爆炸的4个原因

    来源:医药养生保健报设计:李雅琴医学审核:姜峰出品人:胡丽丽

  • 高炉
    高炉

    今天这活却是个白事,等到了时辰,那家人便准备火化,本来准备送普炉,我却心中一动,便对那家人说道:“这老人走也不要省,还是送高炉吧。”

  • 高压锅和电压力锅的区别,推荐几款点压力锅
    高压锅和电压力锅的区别,推荐几款点压

    记得之前有一次去朋友家玩,他正在用高压锅煮小米粥,是的,高压锅压小米粥,大概煮了半小时,高压锅突然爆炸了,现场惨不忍睹啊,幸好厨房里没

0