Pyhton操作Neo4j图数据库实践(南北朝隋唐历史北朝主要人物知识图谱)
Posted 肖永威
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pyhton操作Neo4j图数据库实践(南北朝隋唐历史北朝主要人物知识图谱)相关的知识,希望对你有一定的参考价值。
独孤信“第一岳父”之称很形象,他有三个女儿做了三个朝代皇后,以及杨坚、杨广、李渊等人关系。本文试着使用图数据库(neo4j)表达这段南北朝隋唐历史北朝主要人物知识图谱。
1. Neo4j与py2neo
neo4j目前是图数据库的主流,neo4j的Cypher语法简单直观,但是不便于流程化。如果习惯在python环境下处理数据,那么还是要用到python的neo4j库,即py2neo.
py2neo本身并不复杂,但要先适应它的思考模式。另一个问题是py2neo文档的示例较少,而且不同版本的py2neo挺不相同,容易弄混。本文基于Neo4j3.5.x及py2neo 2021.2.3。
创建neo4j图数据库有常用数据库接口(py2neo )和数据库语言(Cypher)两种方法,本文重点采用python程序py2neo 方法。
安装Pyhton操作Neo4j图数据库驱动接口
pip install py2neo
第一步:连接图数据库。
from py2neo import Graph,Node,Relationship
##连接neo4j数据库,输入地址、用户名、密码
graph = Graph('http://192.168.19.229:7474/',auth=('neo4j','1526') ) #username='neo4j',password='1526')
graph
Graph('http://192.168.19.229:7474')
2. 创建实体与关系
2.1. 创建节点Node
##创建结点
# 如果使用lable='',则是表示Property Keys
#person_node_1 = Node(label='person',name='李渊',dynasty=['隋朝','唐朝'],post=['唐高祖'])
person_node_1 = Node('person',name='李渊',dynasty=['隋朝','唐朝'],post='唐高祖')
person_node_2 = Node('person',name='李世民',dynasty=['隋朝','唐朝'],post='唐太宗')
person_node_3 = Node('person',name='独孤曼陀',dynasty=['隋朝','北周'],post='元贞皇后')
person_node_4 = Node('person',name='杨广',dynasty='隋朝',post='隋炀帝')
person_node_5 = Node('person',name='杨坚',dynasty=['隋朝','北周'],post='隋文帝')
person_node_6 = Node('person',name='独孤伽罗',dynasty=['隋朝','北周'],post='文献皇后')
person_node_7 = Node('person',name='独孤信',dynasty=['西魏','北周'],post='柱国大将军')
person_node_8 = Node('person',name='萧皇后',dynasty=['梁朝','隋朝','唐朝'],post='皇后')
person_node_9 = Node('person',name='独孤皇后',dynasty='北周',post='独孤皇后')
person_node_10 = Node('person',name='宇文毓',dynasty='北周',post='周明帝')
2.2. 创建关系Relationship
R_12 = Relationship(person_node_1, '父子', person_node_2)
R_31 = Relationship(person_node_3, '母子', person_node_1)
R_36 = Relationship(person_node_3, '姊妹', person_node_6)
R_64 = Relationship(person_node_6, '母子', person_node_4)
R_56 = Relationship(person_node_5, '夫妻', person_node_6)
R_76 = Relationship(person_node_7, '父女', person_node_6)
R_73 = Relationship(person_node_7, '父女', person_node_3)
R_54 = Relationship(person_node_5, '父子', person_node_4)
R_48 = Relationship(person_node_4, '夫妻', person_node_8)
R_79 = Relationship(person_node_7, '父女', person_node_9)
R_90 = Relationship(person_node_10, '夫妻', person_node_9)
注,有新的写法,源代码中给出:
The positional arguments passed to the constructor identify the nodes to
relate and the type of the relationship. Keyword arguments describe the
properties of the relationship::>>> from py2neo import Node, Relationship >>> a = Node("Person", name="Alice") >>> b = Node("Person", name="Bob") >>> a_knows_b = Relationship(a, "KNOWS", b, since=1999)
This class may be extended to allow relationship types names to be
derived from the class name. For example::>>> WORKS_WITH = Relationship.type("WORKS_WITH") >>> a_works_with_b = WORKS_WITH(a, b) >>> a_works_with_b (Alice)-[:WORKS_WITH {}]->(Bob)
2.3. 按事务管理,写入/删除数据
2.3.1. 写入/创建
# 事务开始
tx = graph.begin()
# 创建节点
tx.create(person_node_1)
tx.create(person_node_2)
tx.create(person_node_4)
tx.create(person_node_5)
tx.create(person_node_6)
tx.create(person_node_3)
tx.create(person_node_7)
tx.create(person_node_8)
tx.create(person_node_9)
tx.create(person_node_10)
# 创建关系
tx.create(R_12)
tx.create(R_31)
tx.create(R_36)
tx.create(R_64)
tx.create(R_56)
tx.create(R_76)
tx.create(R_73)
tx.create(R_54)
tx.create(R_48)
tx.create(R_79)
tx.create(R_90)
# (事务)提交数据
graph.commit(tx)
2.3.2. 删除
# 删除节点
#graph.delete(person_node_1)
#graph.delete(person_node_2)
如果使用delete删除关系,则将相关的节点也删除。
3. 增删节点与关系
对于增删操作,与传统数据库一样,最好先判断节点、关系是否存在,本文暂时不具体展开介绍。
3.1. 查询节点补充建立关系
# 增补节点和关系
person_node_18 = Node('person',name='宇文阐',dynasty='北周',post='周静帝')
# nodes = NodeMatcher(graph)
# 增补关系,先把节点查询出来
node_p1 = graph.nodes.match('person',name='宇文泰').first()
node_p2 = graph.nodes.match('person',name='宇文毓').first()
node_p3 = graph.nodes.match('person',name='宇文赟').first()
node_p3
Node(‘person’, dynasty=‘北周’, name=‘宇文赟’, post=‘北周宣帝’)
node_d = graph.nodes.match('dynasty',name='北周').first()
node_d
Node(‘dynasty’, name=‘北周’, region=‘北朝’)
R_1 = Relationship(node_p1, '父子', node_p2)
R_2 = Relationship(node_p3, '父子', person_node_18)
RDP_1 = Relationship(person_node_18, '亡国',node_d )
tx = graph.begin()
tx.create(person_node_18)
tx.create(R_1)
tx.create(R_2)
tx.create(RDP_1)
graph.commit(tx)
打开浏览器,http://localhost:7474/browser/,将给出如下的图。
这张图有点问题,宇文泰是西魏权臣掌控者,在其去世后,由其侄子宇文护扶持其子宇文觉建立了北周,修改一下。
3.2. 删除错误的关系并修改
删除宇文泰与北周的关系,新建立与西魏的关系。其中,删除关系是指解除分离的含义,使用separate()断开关系。
#查找北周的臣民
node_d = graph.nodes.match('dynasty',name='北周').first()
node_p1 = graph.nodes.match('person',name='宇文泰').first()
relation_1 = graph.match_one((node_d,node_p1),r_type='国人')
print(relation_1)
#graph.delete(relation_1) #将删除关系及相关的节点(node)
graph.separate(relation_1)
(北周)-[:国人 {}]->(宇文泰)
#补充关系
node_p1 = graph.nodes.match('person',name='宇文泰').first()
node_d1 = graph.nodes.match('dynasty',name='西魏').first()
node_p2 = graph.nodes.match('person',name='独孤信').first()
RDP_1 = Relationship(node_d1, '国人', node_p1)
RDP_2 = Relationship(node_d1, '国人', node_p2)
tx = graph.begin()
tx.create(RDP_1)
tx.create(RDP_2)
graph.commit(tx)
修改后的效果图如下所示,还是有些问题,欢迎读者补充完善。
4. 关于基本常用查询
4.1. 节点node查询
node_d = graph.nodes.match('dynasty')
for rel in node_d:
print(rel['name'],rel['region'])
西魏 北朝
梁朝 南朝
隋朝 中国
唐朝 中国
北周 北朝
陈朝 南朝
node_d = graph.nodes.match('dynasty').where("_.region='北朝'")
for rel in node_d:
print(rel['name'],rel['region'])
西魏 北朝
北周 北朝
4.2. 关系Relationship查询
#查询关系是’国人‘的所有关系(relationship)
relation_1 = graph.match_one(r_type='国人')
relation_1
国人(Node('person', dynasty='陈朝', name='广德公主', post='隋炀帝嫔妃'), Node('dynasty', name='陈朝', region='南朝'))
#查找北周的臣民,match(nodes=None,r_type,**properties)
#node顺序为:开始节点,结束节点(可省略结束节点)
node_d = graph.nodes.match('dynasty',name='北周').first()
relation_1 = graph.match((node_d,),r_type='国人')
for rel in relation_1:
print(rel)
print(rel.start_node['name'], rel.end_node['name'], rel.end_node['post'])
relation_3 = graph.match_one((node_d,),r_type='国人')
print(relation_3)
node_p1
(北周)-[:国人 {}]->(宇文邕)
北周 宇文邕 北周武帝
(北周)-[:国人 {}]->(宇文泰)
北周 宇文泰 太师
(北周)-[:国人 {}]->(宇文赟)
北周 宇文赟 北周宣帝
(北周)-[:国人 {}]->(宇文毓)
北周 宇文毓 周明帝
(北周)-[:国人 {}]->(独孤皇后)
北周 独孤皇后 独孤皇后
(北周)-[:国人 {}]->(独孤伽罗)
北周 独孤伽罗 文献皇后
(北周)-[:国人 {}]->(独孤曼陀)
北周 独孤曼陀 元贞皇后
(北周)-[:国人 {}]->(独孤信)
北周 独孤信 柱国大将军
(北周)-[:国人 {}]->(宇文邕)
Node('person', dynasty='西魏', name='宇文泰', post='太师')
5. 补充数据库语言(Cypher)常用语句
- 删除所有内容,清空数据库:
MATCH (n)
DETACH DELETE n
- 删除所有person节点,自动删除关系:
MATCH (n:person)
DETACH DELETE n
- 删除person和dynasty多种节点:
MATCH (n:person),(m:dynasty)
DETACH DELETE n,m
- 查询多节点:
MATCH (n:dynasty),(m:person) RETURN n,m
- 提高查询速度,创建索引:
CREATE INDEX ON :person(name)
6. 小结
在中国的历史长河之中,历史人物及其典故众多,基于图数据库的知识图谱将为我们学习、掌握历史提供新思维,便于整理掌握。
关于知识图谱的使用,后续将逐步展开学习,欢迎一起研究。
参考:
肖永威. Neo4j图数据库入门实践. CSDN博客, 2021.10
The Py2neo Handbook, 2021.1
以上是关于Pyhton操作Neo4j图数据库实践(南北朝隋唐历史北朝主要人物知识图谱)的主要内容,如果未能解决你的问题,请参考以下文章