当前位置: 首页 > news >正文

【云原生】Neo4j 图数据库从搭建到项目使用深度详解

目录

一、前言

二、图数据库介绍

2.1 什么是图数据库

2.2 图数据库的核心思想

2.3 图数据库核心概念

2.4 主流的图数据库解决方案

2.5 图数据库应用场景

2.6 图数据库优缺点

三、Neo4j 图数据库介绍

3.1 什么是 Neo4j

3.2 Neo4j 特点与功能

3.2.1 Neo4j 核心特点

3.2.2 Neo4j 核心功能

3.3 Neo4j 优点

3.4 Neo4j 数据模型

3.4.1 图论基础

3.4.2 属性图模型

3.4.3 Neo4j 的构建元素

四、基于Docker搭建 Neo4j

4.1 搭建过程

4.1.1 下载镜像

4.1.2 创建目录

4.1.3 启动容器

4.1.4 访问neo4j web界面

五、Neo4j 技术使用深度详解

5.1 数据准备

5.2 Neo4j数据操作命令使用

5.2.1 创建节点

5.2.2 创建节点指定标签

5.2.3 创建节点之间的关系

5.3 Neo4j 查询详解

5.3.1 查询语法

5.3.2 基本数据查询

5.3.3 关系深度查询

5.3.4 分页查询

5.3.5 更新数据

5.3.6 删除数据

5.4 索引操作

5.4.1 创建索引

5.4.2 删除索引

六、写在文末


一、前言

随着社交,电商,金融,零售,物联网等行业的发展,现实社会的关系构成了一张复杂而庞大的关系网,而传统数据库很难处理关系运算,纵然是大数据技术,面临着数据量的不断增长时,在处理数据关系时也会面临算力的瓶颈,因此急需一种支持海量数据关系计算的数据库,图数据库就随之产生了。

二、图数据库介绍

2.1 什么是图数据库

图数据库(Graph Database)是一种专门用于存储和查询图结构数据的数据库。它不同于传统的关系型数据库(如 MySQL、Oracle,用表和列存储数据)和 NoSQL 数据库(如 MongoDB,用文档存储数据),其核心在于直接以“图”的方式来存储、管理和处理数据之间的关系。比如在下面这张图中,就在一张图形化的结构中很好的展示了数据之间的关系。

在这样一张关系图谱中,假如要查一下Tom Tykwer这个人与 Frank Darab 两者间的关系,使用关系型数据库来做,估计是具有的难度。

类似的关系场景还有很多,有些节点上甚至包含了很多属性值,类似这样的应用程序中,数据节点包含了大量的结构化,半结构化,甚至非结构化的连接数据。在传统的RDBMS数据库中,想要表示这种非结构化的连接数据并不简单,如果我们在RDBMS数据库中存储这种连接数据,那么检索或遍历是非常困难,而且性能是非常低效的,所以要表示或存储这种更多需要连接的数据,应该选择一个图数据库来做这件事。

使用图数据库,就能非常容易的存储这种更多需要连接的数据。它将每个配置文件数据作为节点的数据存储在内部,通过与相邻的节点连接,构成关系,这样就形成了关系图谱,检索和遍历也就非常容易且更加高效。

2.2 图数据库的核心思想

图数据库的核心思想叫:以关系为中心

  • 传统数据库在处理复杂、多跳的关系查询时(例如“朋友的朋友的朋友是谁?”),需要通过大量的JOIN操作,性能会随着数据量和关联深度的增加而急剧下降。

  • 图数据库将关系提升为一等公民。关系和数据本身同等重要,直接存储在数据库中。这使得它在这种深度关联查询上具有极高性能的优势,通常能以常数级的时间复杂度找到关联,无论图有多大。

2.3 图数据库核心概念

为了后续更好的学习和掌握图数据库的技术,需要提前了解一点关于图数据库的概念,图数据库的理论基础来自数学的图论。一个图由以下两部分组成:

  • 节点(Node / Vertex):代表实体或对象。

    • 例如:一个人、一件商品、一家公司、一个IP地址。

  • 关系(Relationship / Edge):代表节点之间的连接。

    • 例如:认识(KNOWS)购买(BOUGHT)属于(BELONGS_TO)攻击(ATTACKED)

    • 关系总是有方向的(从一个节点指向另一个节点)和类型的,并且可以有属性。

  • 属性(Property):

    • both 节点和关系都可以拥有属性,即键值对(Key-Value Pair),用于存储实体的特征或关系的详细信息。

      • 节点属性:例如,一个“人”节点可以有 姓名年龄城市 等属性。

      • 关系属性:例如,一个“购买”关系可以有 购买时间金额数量 等属性。

  • 标签(Label):

    • 用于对节点进行分组,类似于关系型数据库中的表。

    • 例如:一个节点可以有 PersonCustomer 两个标签。

2.4 主流的图数据库解决方案

经过多年的发展和应用,也出现了很多关于图数据库解决方案,下面列举几种比较常用的主流的图数据库产品

  1. Neo4j:最著名、使用最广泛的图数据库,开源和企业版。拥有强大的社区和生态系统。

  2. Amazon Neptune:由 AWS 提供的全托管图数据库服务,同时支持属性图模型和 RDF 模型。

  3. TigerGraph:分布式原生图数据库,主打处理大规模数据和深度链接分析,企业级应用较多。

  4. JanusGraph:一个开源的、可扩展的图数据库,支持多种存储后端(如 Cassandra、HBase)。

  5. Nebula Graph:国产开源分布式图数据库,性能出色,在国内社区非常活跃。

2.5 图数据库应用场景

图数据库非常适合处理高度互联的数据和复杂关系的查询。下面介绍了图数据库的一些应用场景:

1)社交网络:

  • 发现潜在朋友(一度、二度人脉)。

  • 影响力分析(寻找关键意见领袖)。

  • 信息传播路径追踪。

2)金融风控与反欺诈:

  • 识别欺诈团伙:通过分析交易关系、设备共享、IP关联等,发现隐藏的欺诈环。

  • 实时检测异常交易模式。

3)推荐系统

  • “购买此商品的顾客也购买了...”:基于商品的协同过滤。

  • “关注了这位歌手的人也关注了...”:基于用户的协同过滤。

  • 实现非常精准和实时的个性化推荐。

4)知识图谱

  • 构建复杂的领域知识系统,如医疗知识图谱、企业知识库。

  • 语义搜索和智能问答(Q&A)。

5)IT 与网络安全:

  • 分析网络拓扑和依赖关系。

  • 追踪安全事件,分析攻击路径,找出漏洞根源。

6)供应链与物流:

  • 跟踪物品从原材料到成品的全链路。

  • 优化物流路线,分析中断风险。

2.6 图数据库优缺点

优点:

  • 关系查询性能极高:处理深度关联查询的优势是压倒性的。

  • 敏捷灵活:数据模型非常灵活,易于扩展和变更,无需像关系数据库一样预先设计复杂的表结构。

  • 表达直观:图模型非常符合人类对现实世界的认知(万物互联),无论是建模还是查询都更直观。

缺点:

  • 不适合非关联数据:如果您的数据大多是独立的、没有复杂关系的,使用图数据库可能是一种浪费。

  • 事务处理:虽然许多图数据库支持 ACID 事务,但在超大规模分布式环境下,其事务性能可能不如一些为此优化的键值或文档数据库。

  • 学习曲线:需要学习新的查询语言(如 Cypher)和图思维方式。

  • 生态系统:虽然正在快速发展,但其工具和生态的丰富程度仍不如成熟的关系型数据库。

三、Neo4j 图数据库介绍

3.1 什么是 Neo4j

Neo4j是⽤Java实现的开源NoSQL图数据库。使用scala和java编写。从2003年开始开发,2007年正式发布第⼀版,其源码托管于GitHtb。Neo4j作为图数据库中的代表产品,已经在众多的⾏业项⽬中进⾏了应⽤,如:⽹络管理、软件分析、组织和项⽬管理、社交项⽬等⽅⾯。官网:https://neo4j.com

3.2 Neo4j 特点与功能

3.2.1 Neo4j 核心特点

Neo4j具有下面的特点:

  • Neo4j实现了专业数据库级别的图数据模型的存储,提供了完整的数据库特性,包括ACID事务的⽀持、集群的⽀持、备份和故障转移等。

  • Neo4j提供了申明式的查询语⾔Cypher,它类似于关系型数据库中的SQL语⾔,其具有表现⼒丰富、使⽤简单、查询效率⾼、⾼扩展性等特点。

Neo4j存储的数据格式如下图所示

3.2.2 Neo4j 核心功能

neo4j完整的功能特性总结如下:

  • SQL就像简单的查询语言,即Neo4j CQL;

  • 它遵循属性图数据模型;

  • 它通过使用Apache Lucence 支持索引;

  • 它支持UNIQUE约束;

  • 它包含一个用于执行SQL的UI界面:Neo4j浏览器;

  • 它支持完整的ACID规则;

  • 它采用原生图形库与本地GPE(图形处理引擎);

  • 它支持查询的数据导出到json和xls格式;

  • 它提供了REST API,可以被任何编程语言访问;

  • 它提供了可以通过任何UI MVC(如node js)访问的java脚本;

  • 它支持两种java api ,cypher api 和native api来访问java应用程序;

3.3 Neo4j 优点

综合来说,Neo4j具备如下优点:

  • 它很容易表示连接的数据节点之间的关系;

  • 检索/遍历/导航更多的连接数据简单而且性能高效;

  • 它很容易表示半结构化数据;

  • Neo4j CQL查询语言的命令人性化且可读性高,初学者容易掌握;

  • 数据模型简单而强大;

  • 它无需复杂的连接来检索具有关联关系的数据,因为它很容易检索临近关系的数据节点;

3.4 Neo4j 数据模型

在开始学习neo4j之前,有必要对neo4j的数据模型做一个全面深入的了解,因为在后续的应用中,大部分情况下,都是围绕neo4j数据模型中的各种概念展开。

3.4.1 图论基础

图是由表示一组节点和连接这些节点的关系构成,图形以属性的形式将数据存储在节点和关系中,属性用于表示数据的键值对,在图论中,可以用一个带有圆的节点表示,节点之间的关系用一个箭头做标记,最简单的图即单个节点

比如可以使用节点表示社交网络,单纯的节点无任何属性,比如我们假设这个节点代表社交网络中的某个人,可以向其中填充一些关于这个人的资料信息作为节点属性

可以用下图表示两个节点之间的关系,在此处,两个配置文件之间的关系为跟随 “Follows”,从关系上来说,Node1 遵循 Node2

3.4.2 属性图模型

Neo4j图数据库遵循属性图模型来存储和管理数据,属性图模型规则如下:

  • 表示节点,关系和属性中的数据

  • 节点和关系都包含属性

  • 关系连接节点

  • 属性是键值对

  • 节点用一个圆圈表示,关系用方向键表示

  • 关系具有方向,单向或双向

  • 每个关系包含“开始节点”或“从节点”,和“到节点”或“结束节点”

在属性图数据模型中,关系应该是定向的,如果我们尝试创建没有方向的关系,它将会抛出一个错误消息,在Neo4j中,关系也应该是具有方向性的。如果我们尝试创建没有方向的关系,N4o4j会抛出一个错误消息,“关系应该是有方向性的”。

Neo4j图数据库将所有数据存储在节点和关系中,所以我们不需要任何额外的RDBMS数据库或NoSql数据库来存储Neo4j数据库数据,它以图的形式存储数据,Neo4j采用本机GPE(图形处理引擎),来使用它的本机图存储格式。

图数据库数据模型的主要模块包括:

  • 节点

  • 关系

  • 属性

下图是一张简单的关系图

在上图中,使用圆圈表示节点,使用箭头表示关系,关系是具有方向性的,而节点中的属性,通常使用键值对(key/value)表示。

3.4.3 Neo4j 的构建元素

Neo4j图数据库主要由以下元素构成

  • 节点

  • 属性

  • 关系

  • 标签

  • 数据浏览器

如下图所示,表示两个Person之间的关系

节点:

节点(Node)是图数据库中最基本的元素,用来表示一个实体记录,就像关系数据库库中的一条数据,在Neo4j中,一个节点可以包含多个属性和多个标签(label)。

  • 节点是主要的数据元素

  • 节点通过关系连接到其他节点

  • 节点可以具有一个或多个属性(即存储为键值对的属性)

  • 节点有一个或多个标签,用于描述在图表中的作用

属性:

属性是用于描述图节点和关系的键值对,其中key为一个字符串,值可以通过使用N4o4j中支持的数据类型来表示

  • 属性是命名值,其中名称(键)是字符串

  • 属性可以被索引和约束

  • 可以从多个属性创建复合索引

关系:

关系同样也是图数据库中的基本元素,当数据库中节点已经存在时,需要将节点连接起来构成图,关系就是用以连接两个节点,关系也称为图论的边,其始端和末端必须是节点,关系不能指向空也不能从空发起,关系和节点一样可以包含多个属性,但关系只能有一个类型。

  • 关系连接两个节点

  • 关系是具有方向性的

  • 节点可以具有多个关系甚至递归关系

  • 关系也可以具有一个或多个属性(存储为键值对)

基于方向性,Neo4j关系主要有两种类型

  • 单向关系

  • 双向关系

标签:

标签(Label)将一个公共名称与一组节点或关系相关联,节点或关系可以包含一个或多个标签,我们可以为现有的节点或关系创建新标签,也可以从现有节点或关系中删除标签。

  • 标签用于将节点分组;

  • 一个节点可以具有多个标签;

  • 对标签进行索引可以加速在图中的查找效率;

  • 本机标签索引针对速度进行了优化;

四、基于Docker搭建 Neo4j

Neo4j支持众多平台的部署安装,如:Windows、Mac、Linux等系统。Neo4j是基于Java平台的,所以部署安装前,先保证已经安装了Java虚拟机。为了演示方便,我们使用docker部署Neo4j。

4.1 搭建过程

参考下面的步骤进行搭建。

4.1.1 下载镜像

使用下面的命令下载镜像,版本可以根据自己的需要进行选择

docker pull neo4j:4.4.5

4.1.2 创建目录

创建相关的目录,如数据目录,配置文件目录等,作为与容器的映射,在usr/local下创建一个neo4j的目录,然后在neo4j目录下分别创建data、logs、conf、import 四个目录

data——数据存放的文件夹
logs——运行的日志文件夹
conf——数据库配置文件夹
import——为了大批量导入csv来构建数据库,只能导入.csv格式的文件,要放到这个文件夹下)

4.1.3 启动容器

使用下面的命令启动neo4j容

docker run -d --name neo4j_self \
-p 7474:7474 -p 7687:7687 \
-v /usr/local/neo4j/data:/data \
-v /usr/local/neo4j/logs:/logs \
-v /usr/local/neo4j/conf:/var/lib/neo4j/conf \
-v /usr/local/neo4j/import:/var/lib/neo4j/import \
docker.io/neo4j:4.4.5

4.1.4 访问neo4j web界面

容器正常启动之后,输入本机地址加上端口号即可打开neo4j浏览器,如果是云服务器,需要提前开放上面的两个端口,如下:

默认情况下,首次登录账户/密码为,neo4j/neo4j,登录成功后,将跳转到下面的界面提示你修改密码

密码修改完成后,来到下面的界面就可以开始使用neo4j的可视化界面进行操作了。

五、Neo4j 技术使用深度详解

接下来将深度全面介绍Neo4j 技术点的使用。

5.1 数据准备

紧接着上述访问的web浏览器界面,点击中间的 Open guide,可以导入官方提供的测试数据

到了第二步的时候,点击一下左侧区域的数据,在右侧将会看到类似于创建数据库那样的语句,这就是生成的创建测试数据的

点击右上角的执行按钮,导入成功后,就能看到生成可视化图数据了

5.2 Neo4j数据操作命令使用

Cypher是Neo4j查询语言,类似与关系型数据库中的SQL,一些关键词来源于SQL,比如:CREATE、WHERE、RETRUN等,官方文档:https://neo4j.com/docs/cypher-manual/current/clauses/match/,下面以上述导入的测试数据为例来练习使用常用的Neo4j操作命令。

5.2.1 创建节点

创建节点,该节点具备name属性,n为该节点的变量,创建完成后返回该节点

CREATE (n {name: $value}) RETURN n

比如创建一个物流网点

CREATE (n {name:'杭州拱墅营业部'})

创建完成后,使用查询命令,可以看到这个数据,当然目前是一个孤立的数据节点

左侧也可以切换不同的查看维度,比如以json形式展示如下,包含一个属性,但是没有标签

5.2.2 创建节点指定标签

在上文谈到节点通常带有标签信息,可以通过下面的语句为创建的节点指定标签

CREATE (n:$Tag {name: $value}) 

比如,指定这个节点的标签为middle,然后再次执行

CREATE (n:middle {name:'杭州西湖营业部'})

查看其详细信息,可以看到当前的数据中还包含了标签middle信息

5.2.3 创建节点之间的关系

语法

CREATE (n)-[r:KNOWS]->(m)  //创建n指向m的关系,并且指定关系类型为:KNOWS,r后紧跟着的就是关系名称

示例需求:创建两个银行网点,一级银行网点与二级网点,语句如下

CREATE (n:first_level {name:'杭州银行总部'}) -[r:manager]-> (m:second_level {name:'杭州银行西湖营业部'}) RETURN n,r,m

执行上述的语句,将看到下面的效果

5.3 Neo4j 查询详解

查询可以说是日常工作中使用最多也最高频的语法,为了全方位的练习查询,先准备以下模拟的测试数据,该数据是一组物流转运的测试数据

CREATE (北京市转运中心:OLT {bid: 8001, name: "北京市转运中心", address: "北京市转运中心", location : point({latitude:39.904179, longitude:116.407387})})
CREATE (上海市转运中心:OLT {bid: 8002, name: "上海市转运中心", address: "上海市转运中心", location : point({latitude:31.230525, longitude:121.473667})})
CREATE (南京市转运中心:OLT {bid: 8003, name: "南京市转运中心", address: "南京市转运中心", location : point({latitude:32.059344, longitude:118.796624})})
CREATE (太原市转运中心:OLT {bid: 8004, name: "太原市转运中心", address: "太原市转运中心", location : point({latitude:37.870451, longitude:112.549656})})
CREATE (郑州市转运中心:OLT {bid: 8005, name: "郑州市转运中心", address: "郑州市转运中心", location : point({latitude:34.745551, longitude:113.624321})})CREATE(北京市转运中心)-[:IN_LINE {cost:10684.9}]->(上海市转运中心),(北京市转运中心)<-[:OUT_LINE {cost:10684.9}]-(上海市转运中心),(北京市转运中心)-[:IN_LINE {cost:8993.1}]->(南京市转运中心),(北京市转运中心)<-[:OUT_LINE {cost:8993.1}]-(南京市转运中心),(南京市转运中心)-[:IN_LINE {cost:2699.4}]->(上海市转运中心),(南京市转运中心)<-[:OUT_LINE {cost:2699.4}]-(上海市转运中心),(太原市转运中心)-[:IN_LINE {cost:3609.7}]->(郑州市转运中心),(太原市转运中心)<-[:OUT_LINE {cost:3609.7}]-(郑州市转运中心),(郑州市转运中心)-[:IN_LINE {cost:5659.7}]->(南京市转运中心),(郑州市转运中心)<-[:OUT_LINE {cost:5659.7}]-(南京市转运中心)CREATE (昌平区转运中心:TLT {bid: 90001, name: "昌平区转运中心", address: "昌平区转运中心", location : point({latitude:40.220952, longitude:116.231034})})
CREATE (北京市昌平区新龙城:AGENCY {bid: 100260, name: "北京市昌平区新龙城", address: "龙跃苑四区3号楼底商", phone : "010-53049073,010-53576707", location : point({latitude:40.07544443596149, longitude:116.3470535709328})})
CREATE(北京市昌平区新龙城)-[:IN_LINE {cost:189.7}]->(昌平区转运中心),(北京市昌平区新龙城)<-[:OUT_LINE {cost:189.7}]-(昌平区转运中心)
CREATE (北京市昌平区定泗路:AGENCY {bid: 100280, name: "北京市昌平区定泗路", address: "北七家镇定泗路苍龙街交叉口", phone : "010-86392987", location : point({latitude:40.11765281246394, longitude:116.37212849638287})})
CREATE(北京市昌平区定泗路)-[:IN_LINE {cost:166.2}]->(昌平区转运中心),(北京市昌平区定泗路)<-[:OUT_LINE {cost:166.2}]-(昌平区转运中心)
CREATE (海淀区转运中心:TLT {bid: 90002, name: "海淀区转运中心", address: "海淀区转运中心", location : point({latitude:39.959893, longitude:116.2977})})
CREATE (北京市海淀区小营:AGENCY {bid: 100347, name: "北京市海淀区小营", address: "北京市昌平区回龙观街道金燕龙大厦停车场", phone : "010-86483817,010-86483817,010-86483817", location : point({latitude:40.06177798692319, longitude:116.32706587559049})})
CREATE(北京市海淀区小营)-[:IN_LINE {cost:116.1}]->(海淀区转运中心),(北京市海淀区小营)<-[:OUT_LINE {cost:116.1}]-(海淀区转运中心)
CREATE (北京市海淀区万泉河:AGENCY {bid: 100227, name: "北京市海淀区万泉河", address: "北京市海淀区四季青镇杏石口路47号院", phone : "18521852356", location : point({latitude:39.94882822425318, longitude:116.25707017441161})})
CREATE(北京市海淀区万泉河)-[:IN_LINE {cost:36.8}]->(海淀区转运中心),(北京市海淀区万泉河)<-[:OUT_LINE {cost:36.8}]-(海淀区转运中心)
CREATE(昌平区转运中心)-[:IN_LINE {cost:383.3}]->(北京市转运中心),(昌平区转运中心)<-[:OUT_LINE {cost:383.3}]-(北京市转运中心),(海淀区转运中心)-[:IN_LINE {cost:112.3}]->(北京市转运中心),(海淀区转运中心)<-[:OUT_LINE {cost:112.3}]-(北京市转运中心)
CREATE (浦东新区转运中心:TLT {bid: 90003, name: "浦东新区转运中心", address: "浦东新区转运中心", location : point({latitude:31.221461, longitude:121.544346})})
CREATE (上海市浦东新区南汇:AGENCY {bid: 210057, name: "上海市浦东新区南汇", address: "园春路8号", phone : "18821179169", location : point({latitude:31.035240152911637, longitude:121.73459966751048})})
CREATE(上海市浦东新区南汇)-[:IN_LINE {cost:275.4}]->(浦东新区转运中心),(上海市浦东新区南汇)<-[:OUT_LINE {cost:275.4}]-(浦东新区转运中心)
CREATE (上海市浦东新区周浦:AGENCY {bid: 210127, name: "上海市浦东新区周浦", address: "川周公路3278-8号", phone : "021-68060322", location : point({latitude:31.132409729356993, longitude:121.59815370294322})})
CREATE(上海市浦东新区周浦)-[:IN_LINE {cost:111.6}]->(浦东新区转运中心),(上海市浦东新区周浦)<-[:OUT_LINE {cost:111.6}]-(浦东新区转运中心)
CREATE (奉贤区转运中心:TLT {bid: 90004, name: "奉贤区转运中心", address: "奉贤区转运中心", location : point({latitude:30.918406, longitude:121.473945})})
CREATE (上海市奉贤区东部:AGENCY {bid: 210017, name: "上海市奉贤区东部", address: "上上海市奉贤区洪庙镇洪兰路351", phone : "021-57171717", location : point({latitude:30.917752751719863, longitude:121.67587819184698})})
CREATE(上海市奉贤区东部)-[:IN_LINE {cost:192.9}]->(奉贤区转运中心),(上海市奉贤区东部)<-[:OUT_LINE {cost:192.9}]-(奉贤区转运中心)
CREATE (上海市奉贤区青村:AGENCY {bid: 210442, name: "上海市奉贤区青村", address: "姚家村1127号", phone : "021-57566663,021-57566606", location : point({latitude:30.916946897994983, longitude:121.57954144207972})})
CREATE(上海市奉贤区青村)-[:IN_LINE {cost:100.9}]->(奉贤区转运中心),(上海市奉贤区青村)<-[:OUT_LINE {cost:100.9}]-(奉贤区转运中心)
CREATE(浦东新区转运中心)-[:IN_LINE {cost:68.0}]->(上海市转运中心),(浦东新区转运中心)<-[:OUT_LINE {cost:68.0}]-(上海市转运中心),(奉贤区转运中心)-[:IN_LINE {cost:347.4}]->(上海市转运中心),(奉贤区转运中心)<-[:OUT_LINE {cost:347.4}]-(上海市转运中心)
CREATE (玄武区转运中心:TLT {bid: 90004, name: "玄武区转运中心" , location : point({latitude:32.048644, longitude:118.797779})})
CREATE (江苏省南京市玄武区紫金墨香苑:AGENCY {bid: 25073, name: "江苏省南京市玄武区紫金墨香苑", address: "栖霞区燕尧路100号", phone : "025-58765331,025-83241955,025-83241881", location : point({latitude:32.117016089520305, longitude:118.86319310255513})})
CREATE(江苏省南京市玄武区紫金墨香苑)-[:IN_LINE {cost:98.0}]->(玄武区转运中心),(江苏省南京市玄武区紫金墨香苑)<-[:OUT_LINE {cost:98.0}]-(玄武区转运中心)
CREATE (江苏省南京市玄武区长江路:AGENCY {bid: 25023, name: "江苏省南京市玄武区长江路", address: "观音阁10号", phone : "18521133265,18695799166", location : point({latitude:32.04803554410631, longitude:118.79190455263355})})
CREATE(江苏省南京市玄武区长江路)-[:IN_LINE {cost:5.6}]->(玄武区转运中心),(江苏省南京市玄武区长江路)<-[:OUT_LINE {cost:5.6}]-(玄武区转运中心)
CREATE(玄武区转运中心)-[:IN_LINE {cost:12.0}]->(南京市转运中心),(玄武区转运中心)<-[:OUT_LINE {cost:12.0}]-(南京市转运中心)CREATE (小店区转运中心:TLT {bid: 90005, name: "小店区转运中心" , location : point({latitude:37.736865, longitude:112.565524})})
CREATE (山西省太原市青龙:AGENCY {bid: 351068, name: "山西省太原市青龙", address: "长治路33号经典家园停车场内13号商铺", phone : "0351-2025888", location : point({latitude:37.83589608758359, longitude:112.56059258109424})})
CREATE(山西省太原市青龙)-[:IN_LINE {cost:110.3}]->(小店区转运中心),(山西省太原市青龙)<-[:OUT_LINE {cost:110.3}]-(小店区转运中心)
CREATE (山西省太原市长风街:AGENCY {bid: 351045, name: "山西省太原市长风街", address: "平阳路104号省农机公司院内", phone : "18636100730", location : point({latitude:37.809964384001226, longitude:112.55299317699505})})
CREATE(山西省太原市长风街)-[:IN_LINE {cost:82.1}]->(小店区转运中心),(山西省太原市长风街)<-[:OUT_LINE {cost:82.1}]-(小店区转运中心)
CREATE(小店区转运中心)-[:IN_LINE {cost:149.4}]->(太原市转运中心),(小店区转运中心)<-[:OUT_LINE {cost:149.4}]-(太原市转运中心)CREATE (中原区转运中心:TLT {bid: 90006, name: "中原区转运中心" , location : point({latitude:34.74828, longitude:113.612966})})
CREATE (河南省郑州市郑上路:AGENCY {bid: 371067, name: "河南省郑州市郑上路", address: "中原西路西四环西北角", phone : "0371-55116757,0371-68014786", location : point({latitude:34.74753024533005, longitude:113.57428550005442})})
CREATE(河南省郑州市郑上路)-[:IN_LINE {cost:35.4}]->(中原区转运中心),(河南省郑州市郑上路)<-[:OUT_LINE {cost:35.4}]-(中原区转运中心)
CREATE (河南省郑州市颍河路:AGENCY {bid: 371086, name: "河南省郑州市颍河路", address: "航海西路与西三环交叉口向南300米路西中贸商务", phone : "19139415556", location : point({latitude:34.71593280680163, longitude:113.60398506929064})})
CREATE(河南省郑州市颍河路)-[:IN_LINE {cost:36.9}]->(中原区转运中心),(河南省郑州市颍河路)<-[:OUT_LINE {cost:36.9}]-(中原区转运中心)
CREATE(中原区转运中心)-[:IN_LINE {cost:11.5}]->(郑州市转运中心),(中原区转运中心)<-[:OUT_LINE {cost:11.5}]-(郑州市转运中心)

执行完成之后,使用查询语句看到如下的效果展示,不同的颜色说明是不同的标签,在数据中都有具体的呈现

5.3.1 查询语法

Cypher查询语法如下:

[MATCH WHERE]  //条件查询
[WITH [ORDER BY] [SKIP] [LIMIT]] //查询的结果以管道的形式传递给下面的语句,聚合查询必须使用WITH
RETURN [ORDER BY] [SKIP] [LIMIT] //返回、排序、跳过、返回个数

看到这个有没有觉得与mysql的查询语句有相似的地方

5.3.2 基本数据查询

查询所有数据,数据量大时慎用

MATCH (n) RETURN n 

查询所有标签数据,在上述数据中,标签为物流网点数据

MATCH (n:AGENCY) RETURN n  //查询所有网点(AGENCY)

查询所有与“北京市转运中心”有关系的节点

MATCH (n:OLT {name: "北京市转运中心"}) -- (m) RETURN n,m

语法说明:

  • OLT,转运中心对应的标签名

  • name,节点名称

  • -- ,表示关系,没有箭头指向表示所有与查询节点有关系的数据均返回

查询所有"北京市转运中心"关联的一级转运中心

MATCH (n:OLT {name:"北京市转运中心"}) --> (m:OLT) RETURN n,m

指定关系标签查询,查询关系中指定关系名称为:IN_LINE

MATCH (n:OLT {name:"北京市转运中心"}) -[r:IN_LINE]- (m) RETURN n,r,m

查询赋值与变量,可以将查询到的结果赋值给一个变量,方便后续更多的业务逻辑处理

MATCH p = (n:OLT {name:"北京市转运中心"}) --> (m:OLT) RETURN p

通过 type()函数查询关系类型,通过下面的sql返回两个转运中心的关系

MATCH (n:OLT {name:"北京市转运中心"}) -[r]-> (m:OLT {name:"南京市转运中心"}) RETURN type(r)

5.3.3 关系深度查询

可以指定关系的深度进行查询,语法格式:-[:TYPE*minHops..maxHops]->,在实际业务中,经常会碰到诸如挖掘节点某个维度或指标的深度,在类似的场景下,就需要使用关系深度查询的语法。

查询【北京市转运中心】关系中深度为1~2层关系的节点,下面3种语法都可以

#语法1
MATCH (n:OLT {name:"北京市转运中心"}) -[*1..2]->(m) RETURN *
#语法2
MATCH (n:OLT {name:"北京市转运中心"}) -[*..2]->(m) RETURN *
#语法3
MATCH path = (n:OLT {name:"北京市转运中心"}) -[*..2]->(m)
RETURN path

简单来说,以“北京市转运中心”为中心,查询的效果来看与之有一个或两个点长度对应的关系数据都将会返回

查询关系,relationships()获取结果中的关系,WITH向后传递数据

MATCH path = (n:OLT {name:"北京市转运中心"}) -[*..2]->(m)
WITH n,m, relationships(path) AS r
RETURN r

返回的是关系结果集,通过with函数,可以对上一步得到的查询结果进一步筛选、过滤或处理,从而只返回预期的结果

查询两个网点之间所有的路线,最大深度为6,可以查询到2条路线,其中where即指定具体的筛选条件,就像mysql中指定具体的字段值等于某个数

MATCH path = (n:AGENCY) -[*..6]->(m:AGENCY)
WHERE n.name = "北京市昌平区定泗路" AND m.name = "上海市浦东新区南汇"
RETURN path

查询两个网点之间最短路径,查询深度最大为10,注意这里使用了函数:shortestPath

MATCH path = shortestPath((n:AGENCY) -[*..10]->(m:AGENCY))
WHERE n.name = "北京市昌平区定泗路" AND m.name = "上海市浦东新区南汇"
RETURN path

查询两个网点之间所有的路线中成本最低的路线,最大深度为10(如果成本相同,转运节点最少)

MATCH path = (n:AGENCY) -[*..10]->(m:AGENCY)
WHERE n.name = "北京市昌平区定泗路" AND m.name = "上海市浦东新区南汇"
UNWIND relationships(path) AS r
WITH sum(r.cost) AS cost, path
RETURN path ORDER BY cost ASC, LENGTH(path) ASC LIMIT 1

补充说明:

  • UNWIND是将列表数据展开操作

  • sum()是聚合统计函数,类似还有:avg()、max()、min()等

  • relationships()函数,获得属性的详细信息

查询结果如下,与上面的查询结果类似

5.3.4 分页查询

当数据量特别大的时候,采用分页查询就是不错的选择了,比如,使用上面的数,下面的两个场景的查询

//分页查询网点,按照bid正序排序,每页查询2条数据,第一页
MATCH (n:AGENCY) 
RETURN n ORDER BY n.bid ASC SKIP 0 LIMIT 3//第二页
MATCH (n:AGENCY) 
RETURN n ORDER BY n.bid ASC SKIP 3 LIMIT 3

5.3.5 更新数据

更新数据是使用SET语句进行标签、属性的更新。SET操作是幂等性的。

更新/设置新的属性

MATCH (n:AGENCY {name:"北京市昌平区新龙城"})
SET n.address = "龙跃苑四区3号楼底商101号"
RETURN n

通过remove移除属性

MATCH (n:AGENCY {name:"北京市昌平区新龙城"}) REMOVE n.address RETURN n

没有address属性的增加属性

MATCH (n:AGENCY) WHERE n.address IS NULL SET n.address = "暂无地址" RETURN n

5.3.6 删除数据

删除数据通过DELETE、DETACH DELETE完成。其中DELETE不能删除有关系的节点,删除关系就需要DETACH DELETE了。

//删除节点
MATCH (n:AGENCY {name:"航头营业部"}) DELETE n
//有关系的节点是不能直接删除的
MATCH (n:AGENCY {name:"北京市昌平区新龙城"}) DELETE n
//删除节点和关系
MATCH (n:AGENCY {name:"北京市昌平区新龙城"}) DETACH DELETE n//删除所有节点和关系,慎用!
MATCH (n) DETACH DELETE n

有关系的节点是不能直接删除的,如下,当删除 “北京市昌平区新龙城”这个节点时抛错

5.4 索引操作

在很多数据存储引擎中都有索引的存在,合理使用索引可以提升数据检索效率,在Neo4j中同样也支持索引,对字段做索引可以提升查询速度。

5.4.1 创建索引

语法如下,其中:OPTIONS子句指定索引提供程序和配置。

CREATE [TEXT] INDEX [index_name] [IF NOT EXISTS]
FOR (n:LabelName)
ON (n.propertyName)
[OPTIONS "{" option: value[, ...] "}"]

如下,给AGENCY创建索引

CREATE TEXT INDEX agency_index_bid IF NOT EXISTS FOR (n:AGENCY) ON (n.bid)

5.4.2 删除索引

语法

DROP INDEX index_name

比如删除上面创建的索引

六、写在文末

本文通过较大的篇幅详细介绍了图数据库Neo4j的使用,并通过实际案例操作全面深度演示了Neo4j技术的使用,希望对看到的同学有用,本篇到此结束,感谢观看。

http://www.dtcms.com/a/460859.html

相关文章:

  • 关于网站开发的技术博客女装网站模板
  • Kubernetes(K8s)全场景命令宝典:从新手入门到故障排查全覆盖
  • 基于protobuf实现网络版本通讯录(protobuf 0基础可看)
  • 开源3d数字人学习笔记2025
  • 四大名著智能可视化推演平台
  • 成像系统(十四-2:《手机影像系统揭秘(二):ISP后端处理 - 画质增强与风格化》):从LED冬奥会、奥运会及春晚等大屏,到手机小屏,快来挖一挖里面都有什么
  • jsp ajax网站开发典型实例佟年给韩商言做的网站
  • 【算法】二分查找(二)查找边界二分
  • 【QT】采用fcitx5框架Ubuntu支持中文输入,QT不支持,解决?
  • 在Robosuite中如何使用Xbox游戏手柄操控mujoco仿真中的机械臂?
  • 数据民主化实践:ChatBI赋能全民数据分析
  • 零基础学AI大模型之LangChain链
  • 拱墅区网站建设网页培训机构
  • 潮州网站建设公司青岛市公共资源交易网
  • 告别重复数据烦恼!MySQL ON DUPLICATE KEY UPDATE 优雅解决存在更新/不存在插入难题
  • 开源项目安全性
  • 找网站建设都需要注意哪些云优化 网站建设
  • dockerfile构建案例
  • UiPath2025笔记第七节:B端Ai操控C端Rpa机器人
  • C++ 经典数组算法题解析与实现教程
  • 详解SOA架构,微服务架构,中台架构以及他们之间的区别和联系
  • 【C++学习笔记】伪随机数生成
  • Unity笔记(十二)——角色控制器、导航寻路系统
  • 关于嵌入式硬件需要了解的基础知识
  • 个人电脑做服务器网站目录型搜索引擎有哪些
  • 从赌场到AI:期望值如何用C++改变世界?
  • H3C网络设备 实验三: 搭建两个局域网,使两个局域网相互通信(路由器,自动分配ip,DHCP协议)
  • 【源码+文档+调试讲解】商品进销存管理系统SpringBoot016
  • 制造业中的多系统困境,如何通过iPaaS“破解”
  • CryptoJs 实现前端 Aes 加密