Neo4j 初认识
Neo4j 是一个高性能、嵌入式、轻量级的,NOSQL 图形数据库。
什么是图数据库?
图数据库用图来存储数据,是最接近高性能的一种用于存储数据的数据结构方式之一。让我们跟随下面的图表,用他们来解释图数据库相关概念。我们将跟随图表中箭头方向来读懂图想表达的真正含义。
一个图由无数的节点和关系组成
“一张图 – 数据记录在 → 节点 → 包括的 → 属性里面” 最简单的图是单节点的,一个记录,记录了一些属性。一个节点可以从单属性开始,成长为成千上亿,虽然会有一点点麻烦。从某种意义上讲,将数据用关系连接起来分布到不同节点上才是有意义的。
关系将图各个部分组织起来
“节点 — 被组织 → 关系 — 可以有 → 属性” 关系可以将节点组织成任意的结构,允许一张图被组织成一个列表,一棵树,一张地图,或者一个复杂的实体 – 这个实体本身也是由复杂的,关系高度关联的结构组成。
用 Traversal 进行数据库查询
“一个 Traversal — 导航 → 一张图; 他 — 标示 → 路径 — 包含 → 节点” 一次 Traversal, 你可以理解为是你通过一种算法,从一些开始节点开始查询与其关联的节点,比如你想找到 “我朋友喜欢但我不喜欢的那首音乐是什么呢?”,又或者 “如果断电了,拿下服务器的服务会首影响?”等等问题。
为节点和关系建立索引
“一个索引 — 映射到 → 属性 — 属于 → 节点或者关系” 经常,你想通过某一给定的属性值找到节点或者关系。比起通过遍历我们的图来书,用索引将会更加高效。比如“找到用户名是tony的用户”。
Neo4j是一个图数据库
“一个图数据库 — 管理 → 一张图 和与图相关的 → 索引” Neo4j是一个有商业支持的开源图数据库。他被设计来用于拿下数据不断高速成长的数据存储,用高效的图数据结构代替传统的表设计。用Neo4j工作,您的应用将得到图的所有优越表现,以及您期望的高可靠性。
Neo4j 图数据库的模型和行为
节点
构成一张图的基本元素是节点和关系。在Neo4j中,节点和关系都可以包含属性。 节点经常被用于表示一些实体,但依赖关系也一样可以表示实体。
下面让我们认识一个最简单的节点,他只有一个属性,属性名是name,属性值是Marko:
关系
节点之间的关系是图数据库很重要的一部分。通过关系可以找到很多关联的数据,比如节点集合,关系集合以及他们的属性集合。
一个关系连接两个节点,必须有一个开始节点和结束节点。
因为关系总是直接相连的,所以对于一个节点来说,与他关联的关系看起来有输入/输出两个方向,这个特性对于我们遍历图非常有帮助:
关系在任一方向都会被遍历访问。这意味着我们并不需要在不同方向都新增关系。
而关系总是会有一个方向,所以当这个方向对你的应用没有意义时你可以忽略方向。
特别注意一个节点可以有一个关系是指向自己的:
为了将来增强遍历图中所有的关系,我们需要为关系设置类型。注意 关键字 type 在这可能会被误解,你其实可以把他简单的理解为一个标签而已。
下面的例子是一个有两种关系的最简单的社会化网络图。
节点表使用到的关系和关系类型
功能 | 实现 |
---|---|
get who a person follows | outgoing follows relationships, depth one |
get the followers of a person | incoming follows relationships, depth one |
get who a person blocks outgoing | blocks relationships, depth one |
get who a person is blocked by | incoming blocks relationships, depth one |
下面的放里是一个简单的文件系统,包括一些符号软链接:
根据你看到的,你在遍历的时候会用到关系的方向和关系的类型。
What | How |
---|---|
get the full path of a file | incoming file relationships |
get the paths for a file | incoming file and symbolic link relationships |
get all files in a directory | outgoing file and symbolic link relationships, depth one |
get all files in a directory, excluding symbolic links | outgoing file relationships, depth one |
get all files in a directory, recursively | outgoing file and symbolic link relationships |
属性
节点和关系都可以设置自己的属性。 属性是由Key-Value键值对组成,键名是字符串。属性值是要么是原始值,要么是原始值类型的一个数组。比如+String+,+int+和i+int[]+都是合法的。
注意
null不是一个合法的属性值。 Nulls能代替模仿一个不存在的Key。
属性值类型
Type | Description | Value range |
---|---|---|
boolean | true/false | |
byte | 8-bit integer | -128 to 127, inclusive |
short | 16-bit integer | -32768 to 32767, inclusive |
int | 32-bit integer | -2147483648 to 2147483647, inclusive |
long | 64-bit integer | -9223372036854775808 to 9223372036854775807, inclusive |
float | 32-bit IEEE 754 floating-point number | |
double | 64-bit IEEE 754 floating-point number | |
char | 16-bit unsigned integers representing Unicode characters | u0000 to uffff (0 to 65535) |
String | sequence of Unicode characters |
Neo4j 数据库安装
通过 Docker 安装
从 Neo4j 2.3 开始,Docker 仓库就已经包含社区版和企业版的 Neo4j Docker 镜像。
我们以 Neo4j 3.0+ 版本为例:
默认情况下 Docker 容器会开放三个端口以供连接
7474
for HTTP7473
for HTTPS7687
for Bolt
它还公开了两个卷
/data
允许数据库在容器外被持久化/logs
允许访问 Neo4j 的 Log 文件
下面是启动 Demo,需要根据实际情况进行启动
docker run \
--publish=7474:7474 --publish=7687:7687 \
--volume=$HOME/neo4j/data:/data \
--volume=$HOME/neo4j/logs:/logs \
neo4j
通过 yum 安装
-
首先需要导入 Key
cd /tmp wget http://debian.neo4j.org/neotechnology.gpg.key rpm --import neotechnology.gpg.key
-
然后将 yum repo 添加到
/etc/yum.repos.d/neo4j.repo
cat <<EOF> /etc/yum.repos.d/neo4j.repo [neo4j] name=Neo4j Yum Repo baseurl=http://yum.neo4j.org/stable enabled=1 gpgcheck=1 EOF
-
最后,通过命令安装 Neo4j
yum install neo4j
Neo4j Cypher 快速参考
Neo4j 标签属性图模型
- Nodes – 节点。在其他图模型中称作“点”、 “顶点”、 “对象”。
- Relationships – 关系。在其他图模型中也称作“边”、 “弧”、 “线”。关系拥有类型。
- Properties – 属性,可以定义在节点和关系上。
- Labels – 标签,代表节点的类别。
小结:
- 节点 – 实体或者复杂的数据类型
- 关系 – 连结实体、构造领域数据结构
- 属性 – 实体的属性、关系的量值、元数据
- 标签 – 按照角色、类型对节点分组
Neo4j的Cypher图查询语言
Cypher 专门为图数据库设计的、基于模式匹配的查询语言。
- Declarative / 声明型:定义要找的数据, Cypher会决定怎样是最优的查找方法。
- Expressive / 丰富的表达力:易于被开发人员和业务人员理解。
- Pattern Matching / 模式匹配:人类的思维更加容易识别和接受模式。
Cypher的基本语法
-
节点
节点必须包含在括号 () 内 。
(n:Label1:Label2)
- 标签名前必须有冒号‘:’
- 节点可以有多个标签
- 标签对节点进行分类,类似关系数据库中的表
(n)
- 节点可以没有或不指定标签。
(n:Label {prop: 'value'})
- 节点可以有属性
-
关系
关系两端各有一个
短横线
/减号
,用方括号
包含关系类型,关系类型名前面必须有冒号:
。在其中一端用>
或<
代表关系的方向,也可以没有方向。下面都是合法的关系:
--
,<--
,-->
,-[:DIRECTED]->
-->
或-[r:TYPE]->
- 关系以
短划线
/减号
和方括号
包含 - 与标签一样,关系类型前也必须有冒号
:
- 关系以
<
>
指定关系的方向- 关系在创建时必须指定方向
- 关系在查询时可以不指定方向(表示双向关系)
另外,关系也可以有属性:
-[:KNOWS {since: 2010}]->
-
模式
模式是由关系连接起来的节点构成的表达式,关系可以是
有方向
的,也可以是没有方向
/双向
的。()-[]-() ()-[]->() ()<-[]-()
(n:Label {prop:'value'})-[:TYPE]->(m:Label)
- 最基本的模式:由一类关系连接的两个节点
- 使用变量保存匹配的结果
(p1:Person {name:'Alice'})-[:KNOWS]->(p2:Person {name:'Bob'})
- 如果存在从Alice到Bob的、类型为KNOWS的关系,那么上面的模式会将匹配的节点保存在p1和p2中。
-
查询的组成部分
-
第一种形式
MATCH (m:Movie) RETURN m
MATCH
和RETURN
是Cypher
关键字m
是变量,保存节点:Movie
是标签
-
第二种形式
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie) RETURN p, r, m
MATCH
和RETURN
是Cypher
关键字p
和m
是变量,保存节点r
是变量,保存关系:Movie
是节点标签:ACTED_IN
是关系类型
-
第三种形式
MATCH path = (:Person)-[:ACTED_IN]->(:Movie) RETURN path
MATCH
和RETURN
是Cypher
关键字path
是变量,保存路径:Movie
是节点标签:ACTED_IN
是关系类型
-
-
图查询的结果
MATCH (m:Movie) RETURN m
返回匹配的节点列表,所有节点的标签都是
Movie
。 -
表状数据结果
MATCH (m:Movie) RETURN m.title, m.released
属性以
{variable}.{property_key}
的方式访问。这个查询返回包含两列的表状数据:title
/标题
,和released
/放映年份
。 -
关于大小写
大小写敏感 大小写不敏感 节点标签 Cypher 关键字 关系类型 属性名/键 例如:
大小写敏感 大小写不敏感 :Person
MaTcH
:ACTED_IN
return
name
-
命名规范
- 关键字 – 全部大写(
MATCH
,RETURN
, …) - 标签名 – 首字母大写(
n:Movie
) - 关系名 – 全部大写(
:ACTED_IN
) - 属性名,变量名 – 小写(
m.name
)
- 关键字 – 全部大写(
参考资料
- Neo4j中文社区
- Neo4j with Docker
- Neo4j Stable Yum Repo
- 俞方桦博士的
Neo4j Cypher 快速参考