赞
踩
图数据库(graph database)是一种特殊的数据库,用于存储丰富的关系数据,neo4j是目前最流行的图数据库,支持完整的事务。在属性图中,图由顶点,边,和属性组成,顶点和边都可以设置属性,顶点也称作节点,边称作关系,每个节点和关系都可以有一个或多个属性。neo4j创建的图是用顶点和边构成的有向图,查询语言为cypher。
一般的关系数据库只对单个Join操作进行优化查询,多重Join操作查询的性能会显著下降,图数据库适合查询关系数据,由于图遍历的局部性,不管图中有多少节点和关系,根据遍历规则,Neo4j只访问与遍历相关的节点,不受总数据集大小的影响,遍历的节点越多,遍历速度越慢,但这种速度是线性的变慢。
在关系数据库中,Join操作用于将多个表中的数据合并在一起,以创建一个包含多个表的结果集。
首先安装JDK,需要创建Oracle账号才能下载JDK:https://www.cnblogs.com/huzixia/p/10402200.html
在cmd中测试java是否安装成功:
C:\Users\Administrator>java -version
java version "1.8.0_381"
Java(TM) SE Runtime Environment (build 1.8.0_381-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.381-b09, mixed mode)
然后下载Neo4j Desktop,下载的同时保存Neo4j Desktop Activation Key用于安装激活:https://neo4j.com/deployment-center/
安装成功并激活后打开Neo4j Desktop,新建一个Project,并在其中添加DBMS,比如名称为Graph DBMS,先start再open该数据库。在数据库中创建节点:
create(n:技术论坛{name:'CSDN'})
上面语句的语法为:
CREATE (<node-name>:<label-name>)
CREATE (
<node-name>:<label-name>
{
<Property1-name>:<Property1-Value>
........
<Propertyn-name>:<Propertyn-Value>
}
)
创建后,neo4j会为节点自动添加属性<id>
,然后再创建一个节点:
create(n:课程{name:'知识图谱'})
再创建关系,比如 技术论坛 开设 课程:
match(a:技术论坛),(b:课程)create(a)-[r:开设]->(b)
下面通过手动创建一个简单的电影知识图谱来熟悉neo4j,该图谱包括:创建电影节点,创建导演节点,创建演员节点,创建电影和导演的关系,创建电影和演员的关系。
电影信息为:
首先创建Movie DBMS,进入数据库创建一个电影:
create(n:film{name:'肖申克的救赎',type:'犯罪',score:'9.7'})
也可以同时创建多个电影,注意此时需要不指定node-name,让系统自动添加不同的node-name:
create(:film{name:'霸王别姬',type:'剧情',score:'9.6'}),
(:film{name:'⾟德勒的名单',type:'历史',score:'9.5'}),
(:film{name:'盗梦空间',type:'剧情',score:'9.3'}),
(:film{name:'星际穿越',type:'剧情',score:'9.3'}),
(:film{name:'荆轲刺秦王',type:'历史',score:'8.2'}),
(:film{name:'绿里奇迹',type:'剧情',score:'8.9'})
然后同时创建多个导演:
create(:director{name:'弗兰克·德拉邦特'}),
(:director{name:'陈凯歌'}),
(:director{name:'史蒂⽂·斯⽪尔伯格'}),
(:director{name:'克⾥斯托弗·诺兰'})
同时创建多个演员:
create (:actor {name:'蒂姆·罗宾斯'}),
(:actor {name:'张国荣'}),
(:actor {name:'连姆·尼森'}),
(:actor {name:'⻢修·⻨康纳'}),
(:actor {name:'张丰毅'})
然后创建关系,电影 肖申克的救赎 和导演 弗兰克·德拉邦特 的关系:
MATCH(a:director),(b:film)
WHERE a.name='弗兰克·德拉邦特' AND b.name='肖申克的救赎'
CREATE(a)-[r:direct]->(b)
创建电影和演员的关系:
MATCH(a:actor),(b:film)
WHERE a.name='张国荣' AND b.name='霸王别姬'
CREATE(a)-[r:play]->(b)
创建电影和演员的关系:
MATCH(a:actor),(b:film)
WHERE a.name='蒂姆·罗宾斯' AND b.name='肖申克的救赎'
CREATE(a)-[r:play]->(b)
创建电影和演员的关系:
MATCH(a:actor),(b:film)
WHERE a.name='张丰毅' AND (b.name='霸王别姬' or b.name='荆轲刺秦王')
CREATE(a)-[r:play]->(b)
然后是知识图谱的检索,即查询关系与节点:查询某个电影,查询某个类别下的所有节点,查询两个节点之间的关系,通过函数type获取关系的类型。
比如查询某个电影:
MATCH(a:film)
WHERE a.name='霸王别姬'
RETURN a
查询某个类别下的所有节点:
MATCH(a:director)
RETURN a
查询两个节点之间的关系:
MATCH (:director {name:'弗兰克·德拉邦特'})-[r]->(:film{name:'肖申克的救赎'})
RETURN r
# 返回如下:
╒═════════╕
│r │
╞═════════╡
│[:direct]│
└─────────┘
通过函数type获取关系的类型:
MATCH ()-[r]->(:film{name:'肖申克的救赎'})
RETURN type(r)
# 返回如下:
╒════════╕
│type(r) │
╞════════╡
│"direct"│
├────────┤
│"play" │
└────────┘
增加节点属性:
MATCH(n:film) WHERE n.name='盗梦空间' SET n.language='english'
删除节点属性:
MATCH(n:film) WHERE n.name='盗梦空间' REMOVE n.language
需要安装py2neo:
pip install py2neo
这里以红楼梦构造知识图谱,创建RedChamber数据库,在创建时记住数据库密码,然后打开logs看到:Remote interface available at http://localhost:7474/
,之后我们就可以用py2neo连接该数据库,username统一为neo4j。
通过py2neo连接数据库:
import py2neo
from py2neo import Graph,Node,Relationship,NodeMatcher
# username默认neo4j,密码为数据库创建时的密码,name为数据库中的graph name
g = Graph('http://localhost:7474',user='neo4j',password='12341234',name='neo4j')
这里使用的信息来自http://www.openkg.cn/home,DreamOfRedChamber.csv内容为(见我的资源):
读取该信息:
import pandas as pd
df = pd.read_csv('DreamOfRedChamber.csv')
构建知识图谱:
from tqdm import tqdm
for i, row in tqdm(df.iterrows()):
print(row['head'],row['tail'],row['relation'],row['label'])
start_node = Node("Person",name=row['head'])
g.create(start_node)
end_node = Node("Person",name=row['tail'])
g.create(end_node)
relation = Relationship(start_node,row['label'],end_node)
g.create(relation)
来到 http://localhost:7474/browser/
查询所有人物:
MATCH(a:Person)
RETURN a
放大后可以更清晰看到关系:
我们可以用py2neo运行neo4j的命令:
g.run("match(p:Person {name:'林黛玉'})-[k:丫鬟]-(r)return p,k,r")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。