图数据库Neo4j(最详细教程)
<h1 id="图数据库neo4j实战全网最详细教程">图数据库Neo4j实战(全网最详细教程)</h1><h2 id="1-图数据库neo4j介绍">1. 图数据库Neo4j介绍</h2>
<h3 id="11-什么是图数据库graph-database">1.1 什么是图数据库(graph database)</h3>
<p> 随着社交、电商、金融、零售、物联网等行业的快速发展,现实社会织起了了一张庞大而复杂的关系网,传统数据库很难处理关系运算。大数据行业需要处理的数据之间的关系随数据量呈几何级数增长,急需一种支持海量复杂数据关系运算的数据库,图数据库应运而生。</p>
<p> 世界上很多著名的公司都在使用图数据库,比如:</p>
<ul>
<li>
<p><strong>社交领域:</strong>Facebook, Twitter,Linkedin用它来管理社交关系,实现好友推荐</p>
</li>
<li>
<p><strong>零售领域:</strong>eBay,沃尔玛使用它实现商品实时推荐,给买家更好的购物体验</p>
</li>
<li>
<p><strong>金融领域:</strong>摩根大通,花旗和瑞银等银行在用图数据库做风控处理</p>
</li>
<li>
<p><strong>汽车制造领域:</strong>沃尔沃,戴姆勒和丰田等顶级汽车制造商依靠图数据库推动创新制造解决方案</p>
</li>
<li>
<p><strong>电信领域:</strong>Verizon, Orange和AT&T 等电信公司依靠图数据库来管理网络,控制访问并支持客户360</p>
</li>
<li>
<p><strong>酒店领域:</strong>万豪和雅高酒店等顶级酒店公司依使用图数据库来管理复杂且快速变化的库存</p>
<p>图数据库并非指存储图片的数据库,而是以图数据结构存储和查询数据。</p>
</li>
</ul>
<p><strong>图数据库是基于图论实现的一种NoSQL数据库,其数据存储结构和数据查询方式都是以图论为基础的,图数据库主要用于存储更多的连接数据。</strong></p>
<blockquote>
<p>图论〔Graph Theory〕是数学的一个分支。它以图为研究对象图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。</p>
</blockquote>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122145342126.png" alt="image-20240122145342126" loading="lazy"></p>
<p>使用 Google+(GooglePlus)应用程序来了解现实世界中 Graph 数据库的需求。 观察下面的图表。</p>
<p>在这里,我们用圆圈表示了Google+应用个人资料</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122145513577.png" alt="image-20240122145513577" loading="lazy"></p>
<p>在上图中,轮廓“A”具有圆圈以连接到其他轮廓:家庭圈(B,C,D)和朋友圈(B,C)。</p>
<p>再次,如果我们打开配置文件“B”,我们可以观察以下链接的数据。</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122145608123.png" alt="image-20240122145608123" loading="lazy"></p>
<p> 像这样,这些应用程序包含大量的结构化,半结构化和非结构化的连接数据。 在 RDBMS 数据库中表示这种非结构化连接数据并不容易。如果我们在 RDBMS 数据库中存储这种更多连接的数据,那么检索或遍历是非常困难和缓慢的。所以要表示或存储这种更连接的数据,我们应该选择一个流行的图数据库。<br>
图数据库非常容易地存储这种更多连接的数据。 它将每个配置文件数据作为节点存储在内部,它与相邻节点连接的节点,它们通过关系相互连接。他们存储这种连接的数据与上面的图表中的相同,这样检索或遍历是非常容易和更快的。</p>
<p><strong>关系查询性能对比:</strong></p>
<p> 在数据关系中心,图形数据库在查询速度方面非常高效,即使对于深度和复杂的查询也是如此。在关系型数据库和图数据库(Neo4j)之间进行了实验:在一个社交网络里找到 大深度为5的朋友的朋友,他们的数据集包括100万人,每人约有50个朋友。<br>
实验结果如下:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122145715547.png" alt="image-20240122145715547" loading="lazy"></p>
<p><strong>对比关系型数据库</strong></p>
<table>
<thead>
<tr>
<th>关系型数据库(RDBMS)</th>
<th>图数据库</th>
</tr>
</thead>
<tbody>
<tr>
<td>表</td>
<td>图</td>
</tr>
<tr>
<td>行</td>
<td>节点</td>
</tr>
<tr>
<td>列和数据</td>
<td>属性和关系</td>
</tr>
<tr>
<td>约束</td>
<td>关系</td>
</tr>
</tbody>
</table>
<p>在关系型数据库中,Person和department之间用外键表示关系:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122145935528.png" alt="image-20240122145935528" loading="lazy"></p>
<p>在图数据库中,节点和关系取代表,外键和join:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122145950484.png" alt="image-20240122145950484" loading="lazy"></p>
<p>在图数据库中,无论何时运行类似JOIN的操作,数据库都会使用此列表并直接访问连接的节点,而无需进行昂贵的搜索和匹配计算。</p>
<p><strong>对比其他NoSQL数据库:</strong></p>
<p>NoSQL数据库大致可以分为四类:</p>
<ul>
<li>键值(key/value)数据库</li>
<li>列存储数据库</li>
<li>文档型数据库</li>
<li>图数据库</li>
</ul>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122150423888.png" alt="image-20240122150423888" loading="lazy"></p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122150432767.png" alt="image-20240122150432767" loading="lazy"></p>
<h3 id="12-什么是neo4j">1.2 什么是Neo4j</h3>
<p>Neo4j是一个开源的NoSQL图形数据库,2003 年开始开发,使用 scala和java 语言,2007年开始发布。</p>
<ul>
<li>
<p>是世界上 先进的图数据库之一,提供原生的图数据存储,检索和处理;</p>
</li>
<li>
<p>采用属性图模型(Property graph model),极大的完善和丰富图数据模型;</p>
</li>
<li>
<p>专属查询语言 Cypher,直观,高效;</p>
</li>
</ul>
<p>官网: https://neo4j.com/</p>
<p>Neo4j的特性:</p>
<ul>
<li>SQL就像简单的查询语言Neo4j CQL</li>
<li>它遵循属性图数据模型</li>
<li>它通过使用Apache Lucence支持索引</li>
<li>它支持UNIQUE约束</li>
<li>它包含一个用于执行CQL命令的UI:Neo4j数据浏览器</li>
<li>它支持完整的ACID(原子性,一致性,隔离性和持久性)规则</li>
<li>它采用原生图形库与本地GPE(图形处理引擎)</li>
<li>它支持查询的数据导出到JSON和XLS格式</li>
<li>它提供了REST API,可以被任何编程语言(如Java,Spring,Scala等)访问</li>
<li>它提供了可以通过任何UI MVC框架(如Node JS)访问的Java脚本</li>
<li>它支持两种Java API:Cypher API和Native Java API来开发Java应用程序</li>
</ul>
<p>Neo4j的优点:</p>
<ul>
<li>它很容易表示连接的数据</li>
<li>检索/遍历/导航更多的连接数据是非常容易和快速的</li>
<li>非常容易地表示半结构化数据</li>
<li>Neo4j CQL查询语句命令是人性化的可读格式,非常容易学习</li>
<li>使用简单而强大的数据模型</li>
<li>不需要复杂的连接来检索连接的/相关的数据,因为它很容易检索它的相邻节点或关系细节没有连接或索引</li>
</ul>
<h3 id="13-neo4j数据模型">1.3 Neo4j数据模型</h3>
<p><strong>图论基础</strong></p>
<p> 图是一组节点和连接这些节点的关系,图形以属性的形式将数据存储在节点和关系中,属性是用于表示数据的键值对。<br>
在图论中,我们可以表示一个带有圆的节点,节点之间的关系用一个箭头标记表示。<br>
简单的可能图是单个节点:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122173513650.png" alt="image-20240122173513650" loading="lazy"></p>
<p>我们可以使用节点表示社交网络(如Google+(GooglePlus)个人资料),它不包含任何属性。向Google+个人资料添加一些属性:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122173535513.png" alt="image-20240122173535513" loading="lazy"></p>
<p>在两个节点之间建立关系:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122173558022.png" alt="image-20240122173558022" loading="lazy"></p>
<p>此处在两个配置文件之间创建关系名称“跟随”。 这意味着 Profile-I 遵循 Profile-II。</p>
<p><strong>属性图模型</strong></p>
<p>Neo4j图数据库遵循属性图模型来存储和管理其数据。<br>
属性图模型规则</p>
<ul>
<li>表示节点,关系和属性中的数据</li>
<li>节点和关系都包含属性</li>
<li>关系连接节点</li>
<li>属性是键值对</li>
<li>节点用圆圈表示,关系用方向键表示。</li>
<li>关系具有方向:单向和双向。</li>
<li>每个关系包含“开始节点”或“从节点”和“到节点”或“结束节点”</li>
</ul>
<p> 在属性图数据模型中,关系应该是定向的。如果我们尝试创建没有方向的关系,那么它将抛出一个错误消息。在Neo4j中,关系也应该是有方向性的。如果我们尝试创建没有方向的关系,那么Neo4j会抛出一个错误消息,“关系应该是方向性的”。<br>
Neo4j图数据库将其所有数据存储在节点和关系中,我们不需要任何额外的RDBMS数据库或NoSQL数据库来存储Neo4j数据库数据,它以图的形式存储数据。Neo4j使用本机GPE(图形处理引擎)来使用它的本机图存储格式。</p>
<p>图数据库数据模型的主要构建模块是:</p>
<ul>
<li>节点</li>
<li>关系</li>
<li>属性</li>
</ul>
<p>简单的属性图的例子:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122174024062.png" alt="image-20240122174024062" loading="lazy"></p>
<p>这里我们使用圆圈表示节点。 使用箭头表示关系,关系是有方向性的。 我们可以用Properties(键值对)来表示Node的数据。 在这个例子中,我们在Node的Circle中表示了每个Node的Id属性。</p>
<h3 id="14-neo4j的构建元素">1.4 Neo4j的构建元素</h3>
<p>Neo4j图数据库主要有以下构建元素:</p>
<ul>
<li>节点</li>
<li>属性</li>
<li>关系</li>
<li>标签</li>
<li>数据浏览器</li>
</ul>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122174143756.png" alt="image-20240122174143756" loading="lazy"></p>
<h4 id="节点">节点</h4>
<p>节点(Node)是图数据库中的一个基本元素,用来表示一个实体记录,就像关系数据库中的一条记录一 样。在Neo4j中节点可以包含多个属性(Property)和多个标签(Label)。</p>
<ul>
<li>节点是主要的数据元素</li>
<li>节点通过<strong>关系</strong>连接到其他节点</li>
<li>节点可以具有一个或多个<strong>属性</strong>(即,存储为键/值对的属性)</li>
<li>节点有一个或多个<strong>标签</strong>,用于描述其在图表中的作用</li>
</ul>
<h4 id="属性">属性</h4>
<p>属性(Property)是用于描述图节点和关系的键值对。其中Key是一个字符串,值可以通过使用任何 Neo4j数据类型来表示</p>
<ul>
<li>属性是命名值,其中名称(或键)是字符串</li>
<li>属性可以被索引和约束</li>
<li>可以从多个属性创建复合索引</li>
</ul>
<h4 id="关系">关系</h4>
<p>关系(Relationship)同样是图数据库的基本元素。当数据库中已经存在节点后,需要将节点连接起来 构成图。关系就是用来连接两个节点,关系也称为图论的边(Edge) ,其始端和末端都必须是节点,关系不 能指向空也不能从空发起。关系和节点一样可以包含多个属性,但关系只能有一个类型(Type) 。</p>
<ul>
<li>关系连接两个节点</li>
<li>关系是方向性的</li>
<li><strong>节点</strong>可以有多个甚至递归的关系</li>
<li>关系可以有一个或多个属性(即存储为键/值对的属性)</li>
</ul>
<p>基于方向性,Neo4j关系被分为两种主要类型:</p>
<ul>
<li>单向关系</li>
<li>双向关系</li>
</ul>
<h4 id="标签">标签</h4>
<p>标签(Label)将一个公共名称与一组节点或关系相关联, 节点或关系可以包含一个或多个标签。 我们 可以为现有节点或关系创建新标签, 我们可以从现有节点或关系中删除标签。</p>
<ul>
<li>标签用于将<strong>节点</strong>分组</li>
<li>一个节点可以具有多个标签</li>
<li>对标签进行索引以加速在图中查找节点</li>
<li>本机标签索引针对速度进行了优化</li>
</ul>
<h4 id="neo4j-浏览器">Neo4j 浏览器</h4>
<p>一旦我们安装Neo4j,我们就可以访问Neo4j数据浏览器</p>
<p>访问http://192.168.65.200:7474/browser</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122174653904.png" alt="image-20240122174653904" loading="lazy"></p>
<h4 id="15-使用场景">1.5 使用场景</h4>
<ul>
<li>
<p><strong>欺诈检测</strong></p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122180025445.png" alt="image-20240122180025445" loading="lazy"></p>
</li>
<li>
<p><strong>实时推荐引擎</strong></p>
</li>
</ul>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122180002885.png" alt="image-20240122180002885" loading="lazy"></p>
<h2 id="2-环境搭建">2. 环境搭建</h2>
<p>下载地址:https://neo4j.com/download-center/</p>
<p>安装方式:<br>
1、Neo4j Enterprise Server(企业版)<br>
2、Neo4j Community Server(社区版)<br>
3、Neo4j Desktop(桌面版)</p>
<p>以下为对应的jdk1.8和neo4j的安装包:</p>
<p>链接:https://pan.baidu.com/s/1ZjfP4JJC_QN21j-V_YejrA<br>
提取码:jfqq</p>
<p><strong>安装Neo4j图型数据库步骤:</strong></p>
<p>1.安装jdk1.8</p>
<p>2.安装好jdk后,再安装neo4j</p>
<p>下载好neo4j后,解压完后,配置环境变量:</p>
<p><strong>添加NEO4J_HOME系统变量</strong></p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122183037374.png" alt="image-20240122183037374" loading="lazy"></p>
<p><strong>添加path变量</strong></p>
<pre><code class="language-js">%NEO4J_HOME%\bin
</code></pre>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122183145774.png" alt="image-20240122183145774" loading="lazy"></p>
<p>配置好所有环境变量后,测试一下:</p>
<p>win+r打开运行,在cmd中输入:</p>
<pre><code class="language-js">neo4j.bat console
</code></pre>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122184009311.png" alt="image-20240122184009311" loading="lazy"></p>
<p>启动后输入Http://localhost:7474 ,访问neo4j,默认账号和密码都为neo4j</p>
<h3 id="21安装neo4j-community-server">2.1安装Neo4j Community Server</h3>
<p><strong>注意:</strong> neo4j最新版对应的java版本是jdk17</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122221104393.png" alt="image-20240122221104393" loading="lazy"></p>
<p>jdk8可以下载Neo4j Community Edition 3.5.28</p>
<p>文档:https://neo4j.com/docs/operations-manual/3.5/</p>
<p>解压到新目录(注意:目录名称不要有中文),比如: D:\neo4j\</p>
<pre><code class="language-js"># 将Neo4j作为控制台应用程序运行
<NEO4J_HOME>\bin\neo4j console
# 将Neo4j作为服务使用进行安装
<NEO4J_HOME>\bin\neo4j install-service
</code></pre>
<blockquote>
<p>console: 直接启动 neo4j 服务器</p>
<p>install-service | uninstall-service | update-service : 安装/卸载/更新 neo4j 服务</p>
<p>start/stop/restart/status: 启动/停止/重启/状态</p>
<p>-V 输出更多信息</p>
</blockquote>
<p>进入到bin目录,执行</p>
<pre><code class="language-js">neo4j console
</code></pre>
<p>在浏览器中访问http://localhost:7474</p>
<p>使用用户名neo4j和默认密码neo4j进行连接,然后会提示更改密码。</p>
<p>Neo4j Browser是开发人员用来探索Neo4j数据库、执行Cypher查询并以表格或图形形式查看结果的工 具。</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122221237235.png" alt="image-20240122221237235" loading="lazy"></p>
<h2 id="3-neo4j---cql使用">3. Neo4j --CQL使用</h2>
<h3 id="31-neo4j----cql简介">3.1 Neo4j -- CQL简介</h3>
<p>Neo4j的Cypher语言是为处理图形数据而构建的,CQL代表Cypher查询语言。像Oracle数据库具有查询语言SQL,Neo4j具有CQL作为查询语言。</p>
<ul>
<li>它是Neo4j图形数据库的查询语言。</li>
<li>它是一种声明性模式匹配语言</li>
<li>它遵循SQL语法。</li>
<li>它的语法是非常简单且人性化、可读的格式。</li>
</ul>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122190032230.png" alt="image-20240122190032230" loading="lazy"></p>
<p>三个共同朋友的社交图:</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122190134325.png" alt="image-20240122190134325" loading="lazy"></p>
<p>使用Cypher语言来描述关系:</p>
<pre><code class="language-js">(fox)<-[:knows]-(周瑜)-[:knows]->(诸葛)-[:knows]->(fox)
</code></pre>
<h3 id="32-cql命令使用一">3.2 CQL命令使用一</h3>
<p>CQL命令官方文档:https://neo4j.com/docs/cypher-manual/3.5/clauses/match/</p>
<h4 id="load-csv">LOAD CSV</h4>
<p>导入csv到neo4j</p>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122191026107.png" alt="image-20240122191026107" loading="lazy"></p>
<pre><code class="language-js">#将csv文件拷贝到 %NEO4J_HOME%\import目录
load csv from 'file:///西游记,csv' as line
create (:西游{name:line,tail:line,label:line})
</code></pre>
<h4 id="create-创建">CREATE 创建</h4>
<p>create语句是创建模型语句用来创建数据模型</p>
<h5 id="创建节点">创建节点</h5>
<pre><code class="language-js">#创建简单节点
create (n)
#创建多个节点
create (n),(m)
#创建带标签和属性的节点并返回节点
create (n:person {name:'如来'}) return n
</code></pre>
<h5 id="创建关系">创建关系</h5>
<p>Neo4j图数据库遵循属性图模型来存储和管理其数据。</p>
<p>根据属性图模型,关系应该是定向的。 否则,Neo4j将抛出一个错误消息。</p>
<p>基于方向性,Neo4j关系被分为两种主要类型。</p>
<ul>
<li>单向关系</li>
<li>双向关系</li>
</ul>
<pre><code class="language-js">#使用新节点创建关系
CREATE (n:person {name:'杨戬'})-->(m:person {name:'玉鼎真人'}) return
type(r)
#使用已知节点创建带属性的关系
match (n:person {name:'沙僧'}),(m:person{name:'唐僧'})
create (n)-->(m) return r
#检索关系节点的详细信息
match (n:person)--(m:person) return n,m
</code></pre>
<h5 id="创建全路径">创建全路径</h5>
<pre><code class="language-js">create p=(:person{name:'蛟魔王'})-[:义兄]->(:person{name:'牛魔王'})<-[:义兄]-
(:person {name:'鹏魔王'}) return p
</code></pre>
<h4 id="match-查询">MATCH 查询</h4>
<p>Neo4j CQL MATCH命令用于</p>
<ul>
<li>从数据库获取有关节点和属性的数据</li>
<li>从数据库获取有关节点,关系和属性的数据</li>
</ul>
<pre><code class="language-js">MATCH (n:`西游`) RETURN n LIMIT 25
</code></pre>
<h4 id="return返回">RETURN返回</h4>
<p>Neo4j CQL RETURN子句用于</p>
<ul>
<li>检索节点的某些属性</li>
<li>检索节点的所有属性</li>
<li>检索节点和关联关系的某些属性</li>
<li>检索节点和关联关系的所有属性</li>
</ul>
<pre><code class="language-js">MATCH (n:`西游`) RETURN id(n),n.name,n.tail,n.relation
</code></pre>
<h4 id="where子句">WHERE子句</h4>
<p>像SQL一样,Neo4j CQL在CQL MATCH命令中提供了WHERE子句来过滤MATCH查询的结果。</p>
<pre><code class="language-js">MATCH (n:person) where n.name='孙悟空' or n.name='猪八戒' RETURN n
#创建关系
match (n:person),(m:person) where n.name='孙悟空' and m.name='猪八戒'
create (n)-->(m) return n.name,type(r),m.name
</code></pre>
<h4 id="delete删除">DELETE删除</h4>
<p>Neo4j使用CQL DELETE子句</p>
<ul>
<li>删除节点。</li>
<li>删除节点及相关节点和关系。</li>
</ul>
<pre><code class="language-js"># 删除节点 (前提:节点不存在关系)
MATCH (n:person{name:"白龙马"}) delete n
# 删除关系
MATCH (n:person{name:"沙僧"})<--(m) delete r return type(r)
</code></pre>
<h4 id="remove删除">REMOVE删除</h4>
<p>有时基于客户端要求,我们需要向现有节点或关系添加或删除属性。我们使用Neo4j CQL REMOVE子句 来删除节点或关系的现有属性。</p>
<ul>
<li>删除节点或关系的标签</li>
<li>删除节点或关系的属性</li>
</ul>
<pre><code class="language-js">#删除属性
MATCH (n:role {name:"fox"}) remove n.age return n
#创建节点
CREATE (m:role:person {name:"fox666"})#m:role:person可以给“fox666”既创建role节点又创建person节点
#删除标签
match (m:role:person {name:"fox666"}) remove m:person return m
</code></pre>
<h4 id="set子句">SET子句</h4>
<p>有时,根据我们的客户端要求,我们需要向现有节点或关系添加新属性。要做到这一点,Neo4j CQL提 供了一个SET子句。</p>
<ul>
<li>向现有节点或关系添加新属性</li>
<li>添加或更新属性值</li>
</ul>
<pre><code class="language-js">MATCH (n:role {name:"fox"}) set n.age=32 return n
</code></pre>
<h4 id="order-by排序">ORDER BY排序</h4>
<p>Neo4j CQL在MATCH命令中提供了“ORDER BY”子句,对MATCH查询返回的结果进行排序。</p>
<p>我们可以按升序或降序对行进行排序。默认情况下,它按升序对行进行排序。 如果我们要按降序对它们 进行排序,我们需要使用DESC子句。</p>
<pre><code class="language-js">MATCH (n:`西游`) RETURN id(n),n.name order by id(n) desc
</code></pre>
<h4 id="union子句">UNION子句</h4>
<p>与SQL一样,Neo4j CQL有两个子句,将两个不同的结果合并成一组结果</p>
<ul>
<li>
<p>UNION</p>
<p>它将两组结果中的公共行组合并返回到一组结果中。 它不从两个节点返回重复的行。</p>
<p>限制:</p>
<p> 结果列类型和来自两组结果的名称必须匹配,这意味着列名称应该相同,列的数据类型应该相同。</p>
</li>
<li>
<p>UNION ALL</p>
<p>它结合并返回两个结果集的所有行成一个单一的结果集。它还返回由两个节点重复行。</p>
<p>限制:</p>
<p> 结果列类型,并从两个结果集的名字必须匹配,这意味着列名称应该是相同的,列的数据类型应该是相同的。</p>
</li>
</ul>
<pre><code class="language-js">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
</code></pre>
<h4 id="limit和skip子句">LIMIT和SKIP子句</h4>
<p>Neo4j CQL已提供 <code>LIMIT</code> 子句和<code>SKIP</code>来过滤或限制查询返回的行数。</p>
<p>LIMIT返回前几行,SKIP忽略前几行。</p>
<pre><code class="language-js"># 前两行
MATCH (n:`西游`) RETURN n LIMIT 2
# 忽略前两行
MATCH (n:person) RETURN n SKIP 2
</code></pre>
<h4 id="null值">NULL值</h4>
<p>Neo4j CQL将空值视为对节点或关系的属性的缺失值或未定义值。</p>
<p>当我们创建一个具有现有节点标签名称但未指定其属性值的节点时,它将创建一个具有NULL属性值的新 节点。</p>
<pre><code class="language-js">match (n:`西游`) where n.label is null return id(n),n.name,n.tail,n.label
</code></pre>
<h4 id="in操作符">IN操作符</h4>
<p>与SQL一样,Neo4j CQL提供了一个IN运算符,以便为CQL命令提供值的集合。</p>
<pre><code class="language-js">match (n:`西游`) where n.name in['孙悟空','唐僧'] return id(n),n.name,n.tail,n.label
</code></pre>
<h4 id="index索引">INDEX索引</h4>
<p>Neo4j SQL支持节点或关系属性上的索引,以提高应用程序的性能。</p>
<p>我们可以为具有相同标签名称的所有节点的属性创建索引。</p>
<p>我们可以在MATCH或WHERE或IN运算符上使用这些索引列来改进CQL Command的执行。</p>
<p><strong>Neo4J索引操作</strong></p>
<ul>
<li>Create Index 创建索引</li>
<li>Drop Index 丢弃索引</li>
</ul>
<pre><code class="language-js"># 创建索引
create index on :`西游` (name)
# 删除索引
drop index on :`西游` (name)
</code></pre>
<h4 id="unique约束">UNIQUE约束</h4>
<p>在Neo4j数据库中,CQL CREATE命令始终创建新的节点或关系,这意味着即使您使用相同的值,它也会 插入一个新行。 根据我们对某些节点或关系的应用需求,我们必须避免这种重复。</p>
<p>像SQL一样,Neo4j数据库也支持对NODE或Relationship的属性的UNIQUE约束</p>
<p><strong>UNIQUE约束的优点</strong></p>
<ul>
<li>避免重复记录。 强</li>
<li>制执行数据完整性规则</li>
</ul>
<pre><code class="language-js">#创建唯一约束
create constraint on (n:xiyou) assert n.name is unique
#删除唯一约束
drop constraint on (n:xiyou) assert n.name is unique
</code></pre>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122195458878.png" alt="image-20240122195458878" loading="lazy"></p>
<h4 id="distinct">DISTINCT</h4>
<p>这个函数的用法就像SQL中的distinct关键字,返回的是所有不同值。</p>
<pre><code class="language-js">match (n:`西游`) return distinct(n.name)
</code></pre>
<h3 id="33-常用函数">3.3 常用函数</h3>
<table>
<thead>
<tr>
<th style="text-align: left">函数</th>
<th style="text-align: left">用法</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">String 字符串</td>
<td style="text-align: left">它们用于使用String字面量</td>
</tr>
<tr>
<td style="text-align: left">Aggregation 聚合</td>
<td style="text-align: left">它们用于对CQL查询结果执行一些聚合操作</td>
</tr>
<tr>
<td style="text-align: left">Relationship 关系</td>
<td style="text-align: left">他们用于获取关系的细节,如startnode,endnode等</td>
</tr>
</tbody>
</table>
<h4 id="字符串函数">字符串函数</h4>
<p>与SQL一样,Neo4J CQL提供了一组String函数,用于在CQL查询中获取所需的结果。</p>
<table>
<thead>
<tr>
<th>功能</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>UPPER</td>
<td>它用于将所有字母更改为大写字母</td>
</tr>
<tr>
<td>LOWER</td>
<td>它用于将所有字母改为小写字母</td>
</tr>
<tr>
<td>SUBSTRING</td>
<td>它用于获取给定String的子字符串</td>
</tr>
<tr>
<td>REPLACE</td>
<td>它用于替换一个字符串的子字符串</td>
</tr>
</tbody>
</table>
<pre><code class="language-js">MATCH (e) RETURN id(e),e.name,substring(e.name,0,2)
</code></pre>
<h4 id="aggregation聚合">AGGREGATION聚合</h4>
<p>和SQL一样,Neo4j CQL提供了一些在RETURN子句中使用的聚合函数。 它类似于SQL中的GROUP BY 子句。</p>
<p>我们可以使用MATCH命令中的RETURN +聚合函数来处理一组节点并返回一些聚合值。</p>
<table>
<thead>
<tr>
<th style="text-align: center">聚集功能</th>
<th style="text-align: center">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">COUNT</td>
<td style="text-align: center">它返回由MATCH命令返回的行数</td>
</tr>
<tr>
<td style="text-align: center">MAX</td>
<td style="text-align: center">它从MATCH命令返回的一组行返回最大值</td>
</tr>
<tr>
<td style="text-align: center">MIN</td>
<td style="text-align: center">它返回由MATCH命令返回的一组行的最小值</td>
</tr>
<tr>
<td style="text-align: center">SUM</td>
<td style="text-align: center">它返回由MATCH命令返回的所有行的求和值</td>
</tr>
<tr>
<td style="text-align: center">AVG</td>
<td style="text-align: center">它返回由MATCH命令返回的所有行的平均值</td>
</tr>
</tbody>
</table>
<pre><code class="language-JS">MATCH (e) RETURN count(e)
</code></pre>
<h4 id="关系函数">关系函数</h4>
<p>Neo4j CQL提供了一组关系函数,以在获取开始节点,结束节点等细节时知道关系的细节。</p>
<table>
<thead>
<tr>
<th>功能</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>STARTNODE</td>
<td>它用于知道关系的开始节点</td>
</tr>
<tr>
<td>ENDNODE</td>
<td>它用于知道关系的结束节点</td>
</tr>
<tr>
<td>ID</td>
<td>它用于知道关系的ID</td>
</tr>
<tr>
<td>TYPE</td>
<td>它用于知道字符串表示中的一个关系的TYPE</td>
</tr>
</tbody>
</table>
<pre><code class="language-js">match (a)- ->(b) return id(r),type(r)
</code></pre>
<h3 id="34-neo4j-admin使用数据库备份恢复">3.4 neo4j-admin使用(数据库备份、恢复)</h3>
<h4 id="数据库备份">数据库备份</h4>
<p>对Neo4j数据进行备份、还原、迁移的操作时,要关闭neo4j</p>
<pre><code class="language-js">cd %NEO4J_HOME%/bin
#关闭neo4j
neo4j stop#一定要先neo4j install -service,才可以执行neo4j stop
#备份
neo4j-admin dump --database=graph.db --to=/neo4j/backup/graph_backup.dump
</code></pre>
<h4 id="数据库恢复">数据库恢复</h4>
<p>还原、迁移之前 ,要关闭neo4j服务。</p>
<pre><code class="language-js">#数据导入
neo4j-admin load --from=/neo4j/backup/graph_backup.dump --database=graph.db --
force
#重启服务
neo4j start
</code></pre>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122205236584.png" alt="image-20240122205236584" loading="lazy"></p>
<h2 id="4案例">4.案例</h2>
<h3 id="41创建股票知识图谱">4.1创建股票知识图谱</h3>
<p><img src="https://148342yin-1316298725.cos.ap-beijing.myqcloud.com/images/pic/image-20240122230221660.png" alt="image-20240122230221660" loading="lazy"></p>
<p>创建一个简单的股票知识图谱,包括:</p>
<p><strong>创建节点和关系:</strong></p>
<p>1,建立几只股票的节点</p>
<pre><code class="language-js">create(n:stock{name:'招商银行',code:'600036',launchDate:date("2002-04-09")}),(:stock{name:'中科创达',code:'300496',launchDate:date("2015-12-10")}),(:stock{name:'华工科技',code:'000988',launchDate:date("2000-06-08")}),(:stock{name:'国信证券',code:'002736',launchDate:date("2014-12-29")})
</code></pre>
<p>2,建立上海证券交易所和深圳证券交易所两个节点</p>
<pre><code class="language-js">create(n:SecuritiesExchange{name:'上海证券交易所'}),(:SecuritiesExchange{name:'深圳证券交易所'}) return n;
</code></pre>
<p>3,建立省市地方名称的节点</p>
<pre><code class="language-js">create(n:Province{name:'湖北'}),(:Province{name:'北京'}),(:Province{name:'广东'}) return n;
</code></pre>
<p>4,建立股票和证券交易所关系</p>
<pre><code class="language-js">#建立'国信证券'和'上海证券交易所'的关系
match(a:stock),(b:SecuritiesExchange) where a.name='国信证券' and b.name='上海证券交易所' create (a)-->(b) return r;
#建立'招商银行'和'上海证券交易所'的关系
match(a:stock),(b:SecuritiesExchange) where a.name='招商银行' and b.name='上海证券交易所' create (a)-->(b) return r;
#建立'华工科技'和'深圳证券交易所'的关系
match(a:stock),(b:SecuritiesExchange) where a.name='华工科技' and b.name='深圳证券交易所' create (a)-->(b)
#建立'华工科技'和'深圳证券交易所'的关系
match(a:stock),(b:SecuritiesExchange) where a.name='华工科技' and b.name='深圳证券交易所' create (a)-->(b)
</code></pre>
<p>5,建立股票和省市名称关系</p>
<pre><code class="language-js">#建立'华工科技'和'北京'的关系
match(a:stock),(b:Province) where a.name='华工科技' and b.name='北京' create (a)-->(b)
#建立'中科创达'和'北京'的关系
match(a:stock),(b:Province) where a.name='中科创达' and b.name='北京' create (a)-->(b)
#建立'招商银行'和'湖北'的关系
match(a:stock),(b:Province) where a.name='招商银行' and b.name='湖北' create (a)-->(b)
#建立'国信证券'和'广东'的关系
match(a:stock),(b:Province) where a.name='国信证券' and b.name='广东' create (a)-->(b)
</code></pre>
<pre><code class="language-js">#建立'中科创达'和'国信证券'的关系
create (n:stock{name:'中科创达'})-->(:stock{name:'国信证券'}) return r
#建立'华工科技'和'中科创达'为同行的关系
match(a:stock{name:'华工科技'}),(b:stock{name:'中科创达'}) create (a)-->(b) return type(r)
#建立'华工科技'和'招商银行'为同行的关系
match(a:stock{name:'华工科技'}),(b:stock{name:'招商银行'}) create (a)-->(b) return type(r)
</code></pre>
<p><strong>查询节点和关系:</strong></p>
<p>6,查询某个股票的节点</p>
<pre><code class="language-js">#查询'招商银行'股票节点
match (a:stock) where a.name='招商银行' return a;
</code></pre>
<p>7,查询某个标签的所有节点</p>
<pre><code class="language-js">#查询‘stock’标签的所有节点
match(a:stock) return a;
</code></pre>
<p>8.查询两个节点之间的关系</p>
<pre><code class="language-js">#查询‘华工科技’和‘北京’之间的关系
match(:stock{name:'华工科技'})-->(:Province{name:'北京'}) return type(r)
返回结果:type(r)"Area"
</code></pre>
<p>9,通过函数type获取关系的类型</p>
<pre><code class="language-js">match(:stock{name:'华工科技'})-->() return type(r);
返回结果:type(r)"Area" "Exchange"
</code></pre>
<p><strong>删除节点和关系</strong><br>
10,删除股票的节点</p>
<pre><code class="language-js">#如果该节点存在关系,先删关系,再删节点。
match(a:stock) where a.name='中科创达' delete a
</code></pre>
<p>11,删除某个标签的节点</p>
<pre><code class="language-js">#删除‘stock’标签的节点
match(n:stock) delete n
#删除所有标签节点
match(n) delete n
</code></pre>
<p>12,删除两个节点的关系</p>
<pre><code class="language-js">#删除'中科创达'和'国信证券'之间的关系
match(:stock{name:'中科创达'})-->(:stock{name:'国信证券'}) delete r
#删除'中科创达'节点之间的关系
match(:stock{name:'中科创达'})-->() delete r
</code></pre>
<p>13,删除全部关系</p>
<pre><code class="language-js">#删除'stock'标签的全部关系
match(:stock)-->() delete r
</code></pre>
<p><strong>更新图形</strong><br>
set子句,用于对更新节点的标签和实体的属性;remove子句,用于删除实体的属性和节点的标签;<br>
14,增加节点属性</p>
<pre><code class="language-js">#增加'湖北'节点的属性
match(a:Province) where a.name='湖北' set a.abbreviation='HN' return a
match(a:Province) where a.name='湖北' set a.person='2000' return a
</code></pre>
<p>15,删除节点属性</p>
<pre><code class="language-js">#删除‘湖北’节点属性
match(a:Province) where a.name='湖北' remove a.person
</code></pre>
<h3 id="42-利用cql构建明星关系图谱">4.2 利用CQL构建明星关系图谱</h3>
<pre><code class="language-js">#导入明星数据
load csv from 'file:///明星1.csv' as line
create (:star {num:line,name:line})
load csv from 'file:///明星关系数据1.csv' as line
create (:starRelation
{from:line,subject:line,to:line,object:line,relation:line})
#查询明星关系
match (n:star),(m:starRelation),(s:star) where n.name='刘烨' and m.subject='刘烨'
and s.name=m.object
return n.name,m.relation,s.name
# 创建关系 构建明星关系图谱
match (n:star),(m:starRelation),(s:star) where n.name='刘烨' and m.subject='刘烨'
and s.name=m.object
create (n)-->(s)
return n.name,m.relation,s.name
#查看明星关系
MATCH p=(n:star{name:'刘烨'})-->() RETURN p
# 构建明星全部关系图谱
match (n:star1),(m:starRelation),(s:star1) where n.name=m.subject and s.name=m.object
create (n)-->(s)
# return n.name,m.relation,s.name(可以不写也)
</code></pre>
</div>
<div id="MySignature" role="contentinfo">
<!-- <div id="div_digga" onclick="DiggIt(cb_entryId,cb_blogId,1);" style="position: fixed; right: 20px;bottom: 30px;">
<div class="diggit" style="height: 20px; background-image: none; color: #FFFFFF; background-color: #E33100; border: medium none; font-size: 9pt; font-weight: bold; text-decoration: none; text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);">
<span class="diggnum" style="color: #ffffff;font-size: 9pt;">
顶
</span>
</div>
</div> -->
<!-- <div id="div_diggc" style="position: fixed; right: 140px;bottom: 5px;">
<div class="diggit" style="height: 20px; background-image: none; color: #FFFFFF; background-color: #2DAEBF; border: medium none; font-weight: bold; text-decoration: none; text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);">
<span class="diggnum">
Top
</span>
</div>
</div> -->
<div id="div_diggc" style="position: fixed; right: 20px;bottom: 5px;" onclick="AddToWz(cb_entryId)">
<div class="diggit" style="height: 20px; background-image: none; color: #FFFFFF; background-color: #FFB515; border: medium none; font-weight: bold; text-decoration: none; text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);">
<span class="diggnum" style="color: #FFFFFF;font-size: 9pt;">
收藏
</span>
</div>
</div>
<div id="div_diggb" onclick="my_follow();" style="position: fixed; right: 80px;bottom: 5px;">
<div class="diggit" style="height: 20px; background-image: none; color: #FFFFFF; background-color: green; border: medium none; font-weight: bold; text-decoration: none; text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);">
<span class="diggnum" style="color: #ffffff;font-size: 9pt;">
关注
</span>
</div>
</div>
<div id="div_diggc" style="position: fixed; right: 140px;bottom: 5px;" onclick="$('#tbCommentBody').focus();">
<div class="diggit" style="height: 20px; background-image: none; color: #FFFFFF; background-color: #CDC9C9; border: medium none; font-weight: bold; text-decoration: none; text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);">
<span class="diggnum" style="color: #FFFFFF;font-size: 9pt;">
评论
</span>
</div>
</div><br><br>
来源:https://www.cnblogs.com/yin-jihu/p/17983407
頁:
[1]