下载地址: https://neo4j.com/download/
相关API参考: https://www.w3cschool.cn/neo4j/
1. 简介
图数据库主要用于存储更多的连接数据。如果我们使用 RDBMS 数据库来存储更多连接的数据,那么它们不能提供用于遍历大量数据的适当性能。 在这些情况下,Graph Database 提高了应用程序性能。
(1) 特点
SQL就像简单的查询语言Neo4j CQL
它遵循属性图数据模型
它通过使用Apache Lucence支持索引
它支持UNIQUE约束
它包含一个用于执行CQL命令的UI:Neo4j数据浏览器
它支持完整的ACID(原子性,一致性,隔离性和持久性)规则
它采用原生图形库与本地GPE(图形处理引擎)
它支持查询的数据导出到JSON和XLS格式
它提供了REST API,可以被任何编程语言(如Java,Spring,Scala等)访问
它提供了可以通过任何UI MVC框架(如Node JS)访问的Java脚本
它支持两种Java API:Cypher API和Native Java API来开发Java应用程序
(2) 优点
它很容易表示连接的数据 检索/遍历/导航更多的连接数据是非常容易和快速的 它非常容易地表示半结构化数据 Neo4j CQL查询语言命令是人性化的可读格式,非常容易学习 使用简单而强大的数据模型 它不需要复杂的连接来检索连接的/相关的数据,因为它很容易检索它的相邻节点或关系细节没有连接或索引
neo4j中的主要组成部分:节点(node),关系(relationship),属性(property),标签(label)
节点:一个图形的一个基本单元,表示一个实体
属性:节点和关系都可拥有属性,表示为一个键值对,键名为字符串,值可以是数字,布尔值,字节,字符串,字符串数组,日期。
关系:连接两个节点,包含一个开始节点和一个尾节点。
标签:Label将一个公共名称与一组节点或关系相关联。 节点或关系可以包含一个或多个标签。 我们可以为现有节点或关系创建新标签。 我们可以从现有节点或关系中删除现有标签。
2. Cypher 查询简介
Neo4j CQL支持以下数据类型:
1. boolean 用于表示布尔文字:true,false。 2. byte 用于表示8位整数。 3. short 用于表示16位整数。 4. int 用于表示32位整数。 5. long 用于表示64位整数。 6. float I用于表示32位浮点数。 7. double 用于表示64位浮点数。 8. char 用于表示16位字符。 9. String 用于表示字符串。
Neo4j CQL命令/条款:
1。 CREATE 创建 创建节点,关系和属性 2。 MATCH 匹配 检索有关节点,关系和属性数据 3。 RETURN 返回 返回查询结果 4。 WHERE 哪里 提供条件过滤检索数据 5。 DELETE 删除 删除节点和关系 6。 REMOVE 移除 删除节点和关系的属性 7。 ORDER BY 以…排序 排序检索数据 8。 SET 组 添加或更新标签
Neo4j CQL 函数:
1。 String 字符串 它们用于使用String字面量。 2。 Aggregation 聚合 它们用于对CQL查询结果执行一些聚合操作。 3。 Relationship 关系 他们用于获取关系的细节,如startnode,endnode等。
3. 安装
前提是要先安装JDK,注意JDK版本也有关系,我之前的JDK是11,然后neo4j 服务可以注册成功,但是启动失败,所以需要切换JDK为8
(1) 到https://neo4j.com/download/ 下载安装包
我下载的是社区版: neo4j-community-3.5.5
(2) 安装neo4j 服务 - 到neo4j 的安装目录
neo4j.bat install-service
(3) 启动服务
neo4j.bat console
4.Neo4J使用
Neo4J提供了一个用户友好的web界面,可以进行各项配置、写入、查询等操作,并且提供了可视化功能。类似ElasticSearch一样。
打开浏览器,输入 http://127.0.0.1:7474/browser/ 接下来登录进去即可,默认的账号密码都是:neo4j。 首次登录之后需要修改密码, 例如我的密码修改为neo4j.
5. 练习
neo4j 也会为每个节点分配一个id 属性,类似于MongoDB 生成的docId 属性,自动递增,Id属性的最大值约为35亿。
这里我们建立两种类型的节点: Group 代表班级, Student 代表学生, 其中主要人物关系如下:
Group: 包含一个节点,name为 "宏哥班", num 编号为 "298"
Student: 包含六个学生,name 分别为:(神经、力超、旺懂、旺约、佩奇、畜生), 其中神经是女性,其他的为男性
人物关系和班级关系为:
(1) 除了畜生都属于班级 298
(2) 力超、旺懂、旺约、佩奇 都LIKES 神经, 神经LIKES 力超, 但是 神经和畜生 MARRIED
1. 清除所有的节点
MATCH (n) DETACH DELETE n
2. 创建一个班级节点 (name为为 "宏哥班", 编号改为 "298")
创建班级节点,默认带着name 属性:
CREATE (n:Group {name:'宏哥班'}) RETURN n
可以看到生成一个班级节点:
修改班级: 增加num 属性,和人数属性:
MATCH (a:Group {name:'宏哥班'}) SET a.num = "298", a.total = 55
删除班级节点人数属性:
MATCH (a:Group {name:'Soft1'}) REMOVE a.total
3. 创建人物相关节点:
(1)先建立四个节点
CREATE (n:Student {name:'力超', sex: "男"}) RETURN n CREATE (n:Student {name:'旺懂', sex: "男"}) RETURN n CREATE (n:Student {name:'旺约', sex: "男"}) RETURN n CREATE (n:Student {name:'佩奇', sex: "男"}) RETURN n
(2) 然后建立 神经 和 畜生,并且建立married 关系
CREATE (a:Student {name:'畜生'})-[r:MARRIED]->(b:Student {name:'神经'})
反向建立关系:
MATCH (a:Student {name:'神经'}), (b:Student {name:'畜生'}) MERGE (a)-[:married]->(b)
此时关系图如下:
(3) 建立 力超、旺懂、旺约、佩奇 和 神经的喜欢关系:
- 神经 LIKES 力超, 从2009 年开始, 到2015 年结束 (建立关系的时候给关系建立属性)
MATCH (a:Student {name:'神经'}), (b:Student {name:'力超'}) MERGE (a)-[:LIKES {since:2009, end: 2015}]->(b)
- 力超 LIKES 神经, 从2012 年开始, 到2015 年结束
MATCH (a:Student {name:'力超'}), (b:Student {name:'神经'}) MERGE (a)-[:LIKES {since:2012, end: 2015}]->(b)
- 旺懂喜欢神经
MATCH (a:Student {name:'旺懂'}), (b:Student {name:'神经'}) MERGE (a)-[:LIKES]->(b)
- 旺约喜欢神经
MATCH (a:Student {name:'旺约'}), (b:Student {name:'神经'}) MERGE (a)-[:LIKES]->(b)
- 佩奇 喜欢 神经
MATCH (a:Student {name:'佩奇'}), (b:Student {name:'神经'}) MERGE (a)-[:LIKES]->(b)
- 畜生喜欢神经
MATCH (a:Student {name:'畜生'}), (b:Student {name:'神经'}) MERGE (a)-[:LIKES]->(b)
4. 建立人物和班级之间的关系
MATCH (a:Student {name:'神经'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'力超'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'旺懂'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'旺约'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b) MATCH (a:Student {name:'佩奇'}), (b:Group {name:'宏哥班'}) MERGE (a)-[:BELONGTO{since: 2009, end: 2012}]->(b)
人物关系和班级关系都已经建立完成。
5. 查询
(1) 查询此时的关系图如下:
MATCH (n) RETURN n LIMIT 25
(2) 查询298班的学生
MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) RETURN a,b
(3) 查询298班的学生,名称为神经或者佩奇的
MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) where a.name = "佩奇" or a.name = "神经" RETURN a,b MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) where a.name in ["佩奇", "神经"] RETURN a,b
(4) 查询298班的学生: 按名称逆序排序,前面跳过2个,后面取2个, 类似于mysql 的limit 2, 2 从第三个开始,取两个 (skip和limit 实现分页)
MATCH (a:Student)-[:BELONGTO]->(b:Group {num: "298"}) RETURN a,b order by a.name desc skip 2 limit 2
(5) 查询所有喜欢神经的学生:
MATCH (a:Student)-[:LIKES]->(b:Student {name: "神经"}) RETURN a,b
(6) 查询所有喜欢神经的、并且班级是298班的学生:
MATCH (b:Student {name: "神经"})<-[:LIKES]-(a:Student)-[:BELONGTO]->(c:Group {num: "298"}) RETURN a,b,c
(7) 查询旺懂喜欢的人喜欢的人: (旺懂 -> 神经 -> 力超)
MATCH (a:Student{name: "旺懂"})-[r1:LIKES]-> () -[r2:LIKES]-> (wangdong_likes_likes) RETURN wangdong_likes_likes
(8) 查询所有对外有关系的节点
MATCH (a)-->() RETURN a
(9) 查询所有有关系的节点:
MATCH (a)--() RETURN a
(10). 查询所有对外有关系的节点,以及关系类型
MATCH (a)-[r]->() RETURN a.name, type(r)
(11) 查询有结婚关系的人:
MATCH (n)-[:married]-() RETURN n
6. union/union all (将两组结果中的公共行组合并返回到一组结果中/返回由两个节点重复行) = 结果列类型和来自两组结果的名称必须匹配,这意味着列名称应该相同,列的数据类型应该相同。
类似于Mysql 的union 和 union all
UNION子句语法: <MATCH Command1> UNION <MATCH Command2> UNION ALL子句语法: <MATCH Command1> UNION ALL <MATCH Command2>
7. 函数
===字符串函数
(1) UPPER 它用于将所有字母更改为大写字母
(2) LOWER 它用于将所有字母改为小写字母
(3) SUBSTRING 它用于获取给定String的子字符串
(4) REPLACE 它用于替换一个字符串的子字符串
测试:
创建一个name 为 Alimi 的狗
create (n:Dog {name: 'Amili'}) return n
查询Amili: name 转为大写
match(n:Dog) return upper(n.name)
====AGGREGATION聚合
和SQL一样,Neo4j CQL提供了一些在RETURN子句中使用的聚合函数。 它类似于SQL中的GROUP BY子句。我们可以使用MATCH命令中的RETURN +聚合函数来处理一组节点并返回一些聚合值。
(1) COUNT 它返回由MATCH命令返回的行数。
(2) MAX 它从MATCH命令返回的一组行返回最大值。
(3) MIN 它返回由MATCH命令返回的一组行的最小值。
(4) SUM 它返回由MATCH命令返回的所有行的求和值。
(5) AVG 它返回由MATCH命令返回的所有行的平均值。
测试:
查询Student 标签包含的节点数量:
MATCH (e:Student) RETURN COUNT(*)
查询喜欢神经的人数:
MATCH (a:Student)-[:LIKES]->(b:Student {name: "神经"}) RETURN count(a)
====关系函数
(1) STARTNODE 它用于知道关系的开始节点。
(2) ENDNODE 它用于知道关系的结束节点。
(3) ID 它用于知道关系的ID。
(4) TYPE 它用于知道字符串表示中的一个关系的TYPE。
- 查询喜欢关系的结束节点:
MATCH (a)-[like:LIKES]->(b) RETURN ENDNODE(like)
- 查询喜欢关系的结束节点:并且去重
MATCH (a)-[like:LIKES]->(b) RETURN distinct ENDNODE(like)
- 查询喜欢关系的开始节点:
MATCH (a)-[like:LIKES]->(b) RETURN STARTNODE(like)
8. 索引
Create Index 创建索引
Drop Index 丢弃索引
为Student的name 列创建索引:
CREATE INDEX ON :Student (name)
为Student的name 列删除索引:
DROP INDEX ON :Student (name)
查看索引与约束:
:schema
或者:
call db.indexes
9. 约束 (唯一约束自带Index)
我们也可以创建唯一约束,避免创建多个重复的节点
学生Student的属性name 建立唯一约束:
CREATE CONSTRAINT ON (n:Student) ASSERT n.name IS UNIQUE
查看约束:
再次插入一列进行测试:(报错违反唯一约束)
删除约束:
DROP CONSTRAINT ON (n:Student) ASSERT n.name IS UNIQUE
补充: 根据ID操作节点
根据ID删除节点: MATCH (r) WHERE id(r) = 33 DELETE r RETURN r (有关系不能删除,必须先删除关系) MATCH (r) WHERE id(r) = 33 DETACH DELETE r RETURN r 级联删除, 有关系存在也可以删除 根据ID修改节点: 将畜生name 改为姓赵的畜生 MATCH (r) WHERE id(r) = 32 SET r.name = "姓赵的畜生" 根据ID查询姓赵的畜生 MATCH (r) WHERE id(r) = 32 RETURN r
(1) MATCH语句用于指定的模式检索数据库;OPTIONAL MATCH语句用于搜索模式中描述的匹配项,对于找不到的项,用null代替;在Cypher语句中,类似于SQL语句中的outer join
(2) NEO4J中WITH的用法: 此子句用于将查询部分链接在一起。将其中一个部分的结果输送到下一个部分中作为起点或条件。
例如查询喜欢神经的并且name 为佩奇的:
MATCH (a:Student)-[:LIKES]->(b:Student {name: "神经"}) with a,b where a.name = "佩奇" RETURN a,b
补充: Neo4j中的case 语句
neo4j也有 case 语句, 类似于MySQL的case 语句.例如:将学生 Student 的性别转为数字表示的 性别
MATCH (n:Student) RETURN n.name, CASE n.sex WHEN '男' THEN 1 WHEN '女' THEN 2 ELSE '未知' END AS result
结果:
补充:neo4j别名
neo4j 查询出来起个别民:
MATCH (a:Student) WHERE a.name = "佩奇" RETURN a.name, a.sex
补充:neo4j也有 case 语句, 类似于MySQL的case 语句
例如:将学生 Student 的性别转为数字表示的 性别
MATCH (n:Student) RETURN n.name, CASE n.sex WHEN '男' THEN 1 WHEN '女' THEN 2 ELSE '未知' END AS result
结果:
补充:neo4j 查询出来起个别名:
MATCH (a:Student) WHERE a.name = "佩奇" RETURN a.name, a.sex
补充: merge 命令
MERGE命令: 创建节点,关系和属性;为从数据库检索数据
MERGE命令是CREATE命令和MATCH命令的组合。 MERGE = CREATE + MATCH。 Neo4j CQL MERGE命令语法与CQL CREATE命令类似。
Neo4j CQL MERGE命令在图中搜索给定模式,如果存在,则返回结果;如果它不存在于图中,则它创建新的节点/关系并返回结果。 merge 创建关系或者节点都可以用create 替代。测试如下:
MERGE 语法如下:
MERGE (<node-name>:<label-name> { <Property1-name>:<Pro<rty1-Value> ..... <Propertyn-name>:<Propertyn-Value> })
比如上面我们可以将神经和佩奇建立likes 关系也可以用create, 例如:
match(a:Student{name: "神经"}), (b:Student{name: "佩奇"}) merge (a) -[:LIKES]->(b) return a,b
然后删除这个关系:
match(a:Student{name: "神经"}) -[r:LIKES]-> (b:Student{name: "佩奇"}) delete r
用create 建立关系:
match(a:Student{name: "神经"}), (b:Student{name: "佩奇"}) create (a) -[:LIKES]->(b) return a,b
比如用merge 创建一个节点:
create (a:Dog{name: 'zs'}) // 多次执行会创建多个节点 merge (a:Dog{name: 'zs'}) // 不会创建节点 merge (a:Dog{name: 'zs1'}) // 会创建节点,也就是在节点存在的情况下不会创建节点。 相当于match + create, 先match 匹配,不存在进行create操作
补充: neo4j 也可以多条语句同时执行
neo4j 也可以支持多条语句同时执行, 用分号分割即可。比如:
CREATE INDEX ON :STUDENT (NAME);
CREATE INDEX ON :PERSON (NAME);
也可以建立点的时候建立关系,比如:
merge (a:student{name: '张三'}) set a.sex = '男' merge (b:student{name: '李四'}) set b.sex = '女' MERGE (a)-[:LIKE]->(b)