Neo4j 学习笔记

Neo4j 基础

安装教程

页面介绍

Cypher 学习

命令用法
CREATE创建节点,关系和属性
MATCH检索有关节点,关系和属性
RETURN返回查询结果
WHERE提供条件过滤检索数据
DELETE删除节点和关系
REMOVE删除节点和关系的属性
SET添加或更新标签

官方文档

字符画语法

Cypher 使用字符画来表示模式,使得我们在第一次学习这门语言时很容易记住它。如果你忘记了如何编写,只需要想一想图的样子就会对你有所帮助。

(a)-[:KNOWS]->(b)

主要记住如下几点:

  • 节点由圆括号表示,看起来像是圆圈。就像这样:(node)
  • 关系用箭头来表示。像这样: ->
  • 关系相关的信息可以插入到方括号中。像这样:[:KNOWS]

定义数据

在使用 Cypher 时请记住以下几点:

  • 节点通常有标签(一个或多个)。比如:”Person”,”User”,”Actor”,”Customer”,”Employee” 等
  • 节点通常有属性,属性提供有关节点的额外信息。比如:”name”,”age”,”born” 等
  • 关系也可以有属性
  • 关系通常有一个类型(类似于节点的标签)。比如:”KNOWS”,”LIKES”,”WORKS_FOR”,”PURCHASED” 等

让我们再来看一下上边的例子:

MATCH (p:Person { name:"Homer Flinstone" })
RETURN p

我们可以看到:

  • 节点被圆括号 () 包围
  • Person 是节点的标签
  • name 是节点的属性

创建和删除节点和关系

// 查询操作
// 返回属性 name 为 Homer Flinstone 的 Person 节点
MATCH (p:Person { name:"Homer Flinstone" })
RETURN p
                   
// 创建(多个)节点(展示节点)
CREATE (a:Album { name: "我们是太阳"}, released: "2014"), (b:Album { name: "小水果"}) 
RETURN a,b

// 创建(多个)节点之间的(多个)关系
MATCH (a:Artist),(b:Album),(p:Person)
WHERE a.name = "筷子兄弟" AND b.name = "猛龙过江" AND p.name = "王太利" 
CREATE (p)-[:PRODUCED]->(b), (p)-[:PERFORMED_ON]->(b), (p)-[:PLAYS_IN]->(a)
RETURN a,b,p

// DELETE 子句用在之前例子中的 RETURN 子句的地方。为了安全最好先 RETURN 再 DELETE
// REMOVE 用于删除节点和关系的标签与属性

// 用 REMOVE 将 金轮法王 的 from 属性删除    
MATCH (n:角色) WHERE n.name='金轮法王' 
REMOVE n.from RETURN n
    
// 删除标签为 Album,name 属性为 Panmax 的节点
MATCH (a:Album {name: "Panmax"}) DELETE a; 

// 删除多个节点
MATCH (a:Artist {name: "jiapan"}), (b:Album {name: "Panmax"}) 
DELETE a, b

// 删除所有节点
MATCH (n) DELETE n;

// 删除所有类型为 RELEASED 的关系
MATCH ()-[r:RELEASED]-() 
DELETE r  
                               
MATCH (:Artist {name: "筷子兄弟"})-[r:RELEASED]-(:Album {name: "猛龙过江"}) // 更为具体的删除
DELETE r
                                                      
// DETACH DELETE 子句允许你删除一个节点的同时删除与其相连的所有关系
MATCH (a:Artist {name: "筷子兄弟"}) DETACH DELETE a
MATCH (n) DETACH DELETE n // 删除整个数据库
// MERGE 命令
// MERGE 命令是 CREATE 命令和 MATCH 命令的组合。 MERGE 在图中搜索给定模式,如果存在,则返回结果,如果不存在,则创建并返回结果。
MERGE (n:门派{name:'少林'}) RETURN n // 用法和 CREATE 相同

// SET 子句  SET 用于给现有节点或关系添加新属性,因此,SET 需要配合 MATCH 使用。
match (n:角色) where n.name='杨过' set n.nickname='西狂' return n

// shortestPath 函数用于查找两个节点之间的最短路径
MATCH p=shortestPath(
  (n:角色 {name:"张无忌"})-[*]-(m:武功 {name:"降龙十八掌"})
)
RETURN p  

创建和删除索引

CREATE INDEX ON :Album(name) // 创建索引
DROP INDEX ON :Album(name); // 删除索引
:schema // 查看索引

// 强制索引(索引创建完成后,当你在执行查询时会自动使用)
MATCH (a:Album {name: "猛龙过江"}) 
USING INDEX a:Album(name) 
RETURN a

// 删除之前创建的约束(和它关联的索引)
DROP CONSTRAINT ON (a:Artist) ASSERT a.name IS UNIQUE

当 Neo4j 创建索引时,它会在数据库中创建冗余的副本,因此使用索引会占用更多的硬盘空间并减慢写入速度。因此在决定索引哪些数据时你需要进行一些权衡。

一般来说当你知道某些节点数量很多时,创建索引是个不错的主意。或者你发现查询时间太长可以尝试通过添加索引来解决。

创建约束

Neo4j 入门教程 - 使用 Cypher 创建约束

匹配数据

MATCH 语句用于匹配给定的条件,但实际上它并不返回数据。为了从 MATCH 语句返回数据,我们仍然需要使用 RETURN 子句。

// 根据标签和属性匹配节点
MATCH (p:Person) WHERE p.name = "王太利" RETURN p
MATCH (p:Person {name: "王太利"}) RETURN p 

// 返回全部节点
MATCH (n) return n
                  
// 检索关系
// 想找出哪个乐队发布了名为「猛龙过江」的专辑
MATCH (a:Artist)-[:RELEASED]->(b:Album)
WHERE b.name = "猛龙过江" 
RETURN a

// 匹配任意关系           
match p = (n)-[r]->(m) return p

// 可选匹配,匹配不到内容时返回 null 而不是无结果
optional match p=(n:角色{name:'郭靖'})-[r]->(:作品{name:'倚天屠龙记'}) return p
                                              
// 过滤匹配
MATCH (n:作品)-[]-(m:角色) where m.name='郭靖' return n.name
                 
// 属性存在性检查函数 exists(),匹配所有拥有 desc 属性的节点
match (n) where exists(n.desc)  return n
                                              
//路径长度匹配      
match (n)-[*2]->(m) //表示关系数量为 2 的 3 个节点的匹配,等价于 (a)-[]->()-[]->(b)
           
// 限制结果数量
MATCH (n) RETURN n 
LIMIT 5

FOREACH 函数

foreach 是 Cypher 中列表的更新工具,在 foreach 中,支持 create,merge,delete 和 foreach 对图进行修改。

// 从字符串文本中创建 角色 节点
FOREACH(name in split('郭靖,杨过,张无忌',',') | CREATE(n:角色{name:name}))

导入 CSV 文件

在 Neo4j 中,你可以通过本地或远端 URL 来加载 CSV 文件。

  • 本地 CSV 文件导入
  1. 将 csv 文件放到 $NEO4J_HOME/import 目录下
  2. load csv with headers from 'file:///射雕三部曲.csv' as line
  • 远端 URL 加载
// 没有 headers
LOAD CSV FROM 'https://jpanj.com/2018/neo4j-tutorial-import-data-from-csv-file-using-cypher/genres.csv' AS line
CREATE (:Genre {genreId: line[0], name: line[1]})
MATCH (n:Genre) RETURN n

// 有 headers
LOAD CSV WITH HEADERS FROM 'https://jpanj.com/2018/neo4j-tutorial-import-data-from-csv-file-using-cypher/tracks.csv' AS line
CREATE (:Track { trackId: line.Id, name: line.Track, length: line.Length})
MATCH (n:Track) RETURN n

// 有 headers,分隔符为 ';'
LOAD CSV WITH HEADERS FROM 'https://jpanj.com/2018/neo4j-tutorial-import-data-from-csv-file-using-cypher/tracks.csv' AS line
FIELDTERMINATOR ';'
CREATE (:Track { trackId: line.Id, name: line.Track, length: line.Length})

// 导入大文件,每 1000 行提交一次
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM 'https://jpanj.com/2018/neo4j-tutorial-import-data-from-csv-file-using-cypher/tracks.csv' AS line
CREATE (:Track { trackId: line.Id, name: line.Track, length: line.Length})

统计关系数量

Neo4j 统计关系数量时的技巧

// FATHER:有方向的关系
MATCH ()-[r:FATHER]->() return COUNT(r);
or
MATCH (:Person)-[r:FATHER]->() return COUNT(r);

// FRIEND 没有方向的关系
MATCH ()-[r:FRIEND]->() return COUNT(r);

py2neo

安装

pip install py2neo

连接数据库

from py2neo import Graph
# 连接本地的 Neo4j 数据库,地址为 127.0.0.1,http 端口默认为 7474,用户名和密码分别为 neo4j 与 123
graph = Graph(host='127.0.0.1', http_port=7474, user='neo4j', password='123')

创建节点

从 py2neo 库中导入 Node 类,并通过 Node 类来创建节点实例

from py2neo import Node

# 创建 角色 节点 郭靖,拥有属性 姓名-郭靖,性别-男
guojing = Node('角色',name='郭靖',sex='男')
# 创建 角色 节点 黄蓉,拥有属性 姓名-黄蓉,性别-女
huangrong = Node('角色',name='黄蓉',sex='女')
# 创建 作品 节点 射雕英雄传,拥有属性 名称-射雕英雄传,作者-金庸
shediao = Node('作品',name='射雕英雄传',author='金庸')
# 打印结果
guojing,huangrong,shediao

# 对节点进行操作
guojing['name'] # 获取 key 对应的属性
huangrong['born'] = '桃花岛' # 设置 key 对应属性的 value,如果 key 不存在就创建
del huangrong['born'] # 删除某个属性
len(huangrong) # 返回节点中 property 的个数

# 使用 Graph 中的 create 方法来上传数据到 Neo4j 数据库中
graph.create(guojing) # 在 Neo4j 数据库中创建 郭靖 节点
graph.create(huangrong)
graph.create(shediao)

重新连接数据库创建节点时数据库中会出现相同节点,若要避免这种情况,就需要用到 Graph 中的 merge 方法。

创建关系

通过从 py2neo 库中导入 Relationship 来创建关系 Relationship 依次接收三个参数:节点 - 关系 - 节点,返回 (节点)-[关系]->(节点) 的结果

from py2neo import Relationship

spouse1 = Relationship(guojing,'配偶',huangrong) # 创建郭靖与黄蓉的配偶关系
spouse2 = Relationship(huangrong,'配偶',guojing) # 创建黄蓉与郭靖的配偶关系
inbook1 = Relationship(guojing,'所在作品',shediao) # 创建郭靖与射雕英雄传的所在作品关系
inbook2 = Relationship(huangrong,'所在作品',shediao) # 创建黄蓉与射雕英雄传的所在作品关系

# 对关系进行操作
inbook1['role'] = '男主角' # 设置 key 对应属性的 value
del inbook1['role'] # # 删除某个属性

# 使用 Graph 中的 create 方法来上传数据到 Neo4j 数据库中

graph.create(spouse1) # 创建郭靖与黄蓉的配偶关系
graph.create(spouse2) # 创建黄蓉与郭靖的配偶关系
graph.create(inbook1) # 创建郭靖与射雕英雄传的所在作品关系
graph.create(inbook2) # 创建黄蓉与射雕英雄传的所在作品关系

查找

在 py2neo 中提供了 NodeMatcher 来进行图的查找

from py2neo import NodeMatcher

matcher = NodeMatcher(graph) # 初始化一个 matcher 实例
result = matcher.match("角色", name="郭靖") # 用 match 方法查找 角色 中 name 为郭靖的节点,返回一个 NodeMatch 对象
result.first() # first 方法返回查询结果的第一个
list(result) # 通过 list 来把所有结果显示出来

执行 Cypher 命令

Graph 同时提供 run 方法来直接执行 Cypher 语句

# cypher 语句,对已存在的 郭靖 节点,创建节点和关系 (郭靖)-[父]->(郭啸天)
query = "match (n) where n.name = '郭靖' create (n)-[:父]->(:角色{name:'郭啸天'})"
# 执行 cypher 语句
graph.run(query)

在数据集中存在重复数据的情况,可以先用 python 进行一遍去重,再提交,比用 Cypher 语言去重速度更快。然而在数据量特别大的情况下,py2neo 的速度就没有那么快了

清空 neo4j 数据库

match (n)
detach delete n

用上面的命令可以删除 node 和 relationship,发现有 property keys 删不干净

彻底删除的方法:

  1. neo4j stop
  2. rm -rf $NEO4J_HOME/data/database/X.db

创建新的数据库

由于使用 Neo3.x 创建新数据库而不删除现有数据库,所以只需在 $NEO4J_HOMEconf 的目录编辑 neo4j.conf

搜寻 dbms.active_database=,其默认值应为 graph.db。用其他名称替换它,然后再次启动 neo4j。现在,将在该目录名下创建一个新数据库。若要切换回以前的 db,请重复这些步骤,只需将新值替换为 graph.db 在配置文件中。

数据库存储在$NEO4J_HOME/data/databases 文件中

参考链接

Neo4j 入门教程 - 查询语言 Cypher

知识图谱构建射雕三部曲人物关系[实验楼]

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值