概述
- 在知识图谱领域,Neo4j 是最常用的图数据库之一,而 Py2neo 是 Neo4j 官方推荐的 Python 驱动库,用于在 Python 中便捷地操作 Neo4j 数据库。下面从基础概念到实操示例,介绍如何通过 Py2neo 构建和操作知识图谱。
- 视频资料:
https://pan.quark.cn/s/3e80fafbaae4
一、核心概念
- Neo4j:一种原生图数据库,以“节点(Node)-关系(Relationship)-属性(Property)”的三元组形式存储数据,非常适合表示实体间的复杂关系(如知识图谱中的“人物-关联-事件”)。
- Py2neo:Neo4j 的 Python 客户端库,提供了面向对象的 API,支持创建节点、关系、执行 Cypher 语句(Neo4j 的查询语言)等操作。
二、环境准备
1. 安装 Neo4j
- 下载地址:Neo4j 官方下载(推荐社区版)
- 安装后启动服务:通过 Neo4j 桌面端启动,或命令行启动(默认端口 7474,Web 管理界面为
http://localhost:7474
,初始用户名/密码为neo4j/neo4j
,首次登录需修改密码)。
2. 安装 Py2neo
pip install py2neo # 推荐使用 2021.2.3 及以上版本
三、Py2neo 基础操作
以下示例将构建一个简单的“人物-电影”知识图谱,包含“演员”“导演”等关系。
1. 连接 Neo4j 数据库
首先通过 Graph
类连接到 Neo4j 服务:
from py2neo import Graph, Node, Relationship, Subgraph
# 连接数据库(替换为你的密码)
graph = Graph(
"bolt://localhost:7687", # Neo4j bolt 协议端口(默认 7687)
user="neo4j",
password="你的密码" # 首次登录修改后的密码
)
# 测试连接(清空数据库,仅用于演示)
graph.delete_all() # 生产环境慎用!
2. 创建节点(实体)
节点(Node)代表知识图谱中的“实体”(如人物、电影),可通过 Node
类定义,包含标签(Label,类似实体类型)和属性(Property)。
# 创建“人物”节点
person1 = Node("Person", name="张艺谋", birth_year=1950)
person2 = Node("Person", name="章子怡", birth_year=1979)
# 创建“电影”节点
movie1 = Node("Movie", title="英雄", year=2002, genre="武侠")
movie2 = Node("Movie", title="十面埋伏", year=2004, genre="动作")
# 将节点添加到数据库
graph.create(Subgraph([person1, person2, movie1, movie2]))
- 标签(如 “Person”、“Movie”)用于区分实体类型,一个节点可有多个标签(如
Node("Person", "Director", name="张艺谋")
)。 - 属性(如
name
、year
)是实体的属性信息,支持字符串、数字、列表等类型。
3. 创建关系(关联)
关系(Relationship)表示实体间的关联,通过 Relationship
类定义,包含起始节点、关系类型、结束节点和属性。
# 创建“导演”关系(张艺谋 -> 导演 -> 英雄)
rel1 = Relationship(person1, "DIRECTED", movie1, role="导演")
# 创建“出演”关系(章子怡 -> 出演 -> 英雄)
rel2 = Relationship(person2, "ACTED_IN", movie1, role="女主角")
# 创建“出演”关系(章子怡 -> 出演 -> 十面埋伏)
rel3 = Relationship(person2, "ACTED_IN", movie2, role="女主角")
# 将关系添加到数据库
graph.create(Subgraph([rel1, rel2, rel3]))
此时知识图谱结构如下:
张艺谋 -[DIRECTED]-> 英雄
章子怡 -[ACTED_IN]-> 英雄
章子怡 -[ACTED_IN]-> 十面埋伏
4. 查询数据
Py2neo 支持两种查询方式:面向对象 API 和 Cypher 语句(推荐,更灵活)。
方式 1:面向对象 API 查询
from py2neo import NodeMatcher
# 创建节点匹配器
matcher = NodeMatcher(graph)
# 查询所有“Person”节点
all_people = matcher.match("Person").all()
for p in all_people:
print(p["name"], p["birth_year"]) # 输出:张艺谋 1950;章子怡 1979
# 查询名字为“章子怡”的节点
zhang_ziyi = matcher.match("Person", name="章子怡").first()
print(zhang_ziyi) # 输出:(n1:Person {birth_year:1979, name:"章子怡"})
方式 2:执行 Cypher 语句(推荐)
Cypher 是 Neo4j 的查询语言,功能更强大,可通过 graph.run()
执行:
# 查询章子怡出演的所有电影
result = graph.run("""
MATCH (p:Person {name:"章子怡"})-[r:ACTED_IN]->(m:Movie)
RETURN m.title, r.role, m.year
""").data() # .data() 转换为字典列表
for item in result:
print(f"电影:{item['m.title']},角色:{item['r.role']},年份:{item['m.year']}")
# 输出:
# 电影:英雄,角色:女主角,年份:2002
# 电影:十面埋伏,角色:女主角,年份:2004
5. 更新与删除
更新属性
# 更新“英雄”的评分属性
movie_hero = matcher.match("Movie", title="英雄").first()
movie_hero["rating"] = 8.0 # 添加新属性
graph.push(movie_hero) # 提交更新
删除节点/关系
# 删除“十面埋伏”节点(需先删除其关联的关系)
movie_sm = matcher.match("Movie", title="十面埋伏").first()
if movie_sm:
# 先删除所有与该节点相关的关系
graph.delete(graph.match((None, movie_sm)) | graph.match((movie_sm, None)))
# 再删除节点
graph.delete(movie_sm)
四、批量操作与事务
当处理大量数据(如批量导入实体)时,需使用事务(Transaction)提升效率:
from py2neo import Transaction
# 创建事务
tx = graph.begin()
# 批量创建100个“用户”节点
for i in range(100):
user = Node("User", id=i, name=f"用户{i}")
tx.create(user)
# 提交事务
tx.commit()
五、可视化查询结果
Neo4j 自带的 Web 管理界面(http://localhost:7474
)可直观展示查询结果:
在界面的命令框中输入 Cypher 语句(如 MATCH (n) RETURN n
),即可看到节点和关系的可视化图。
总结
- Neo4j 是知识图谱的理想存储方案,擅长处理实体间的复杂关系。
- Py2neo 提供了简洁的 Python 接口,通过
Graph
、Node
、Relationship
等类可快速操作 Neo4j。 - 实际开发中,建议优先使用 Cypher 语句 进行查询,灵活度更高。
通过以上基础操作,可扩展构建更复杂的知识图谱(如医疗、金融领域),实现实体关联分析、路径查询等功能。