Neo4j 简介以及使用

下载地址: 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    用于表示布尔文字:truefalse2.    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)
【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】
原文地址:https://www.cnblogs.com/qlqwjy/p/14757770.html