Python实战:用Py2neo轻松玩转Neo4j图数据库(附完整代码示例)

张开发
2026/4/17 3:13:31 15 分钟阅读

分享文章

Python实战:用Py2neo轻松玩转Neo4j图数据库(附完整代码示例)
Python实战用Py2neo轻松玩转Neo4j图数据库附完整代码示例当金庸武侠世界遇上图数据库会碰撞出怎样的火花想象一下张无忌的社交网络、明教的人物关系、倚天剑的传承路径——这些错综复杂的关联正是图数据库最擅长的领域。作为Python开发者Py2neo库让我们能够用熟悉的代码风格直接操作Neo4j将节点-关系的思维模型自然映射到代码层面。本文不仅会带你搭建完整的开发环境更会通过武侠案例演示如何用Python代码构建真实的社交图谱分析系统。1. 环境配置与基础连接在开始编写代码之前我们需要准备好以下环境组件Neo4j Desktop官方提供的图形化管理工具包含社区版服务器Python 3.8建议使用虚拟环境隔离依赖Py2neo 2021.1支持最新Neo4j协议的Python驱动安装过程只需两行命令pip install py2neo -i https://pypi.tuna.tsinghua.edu.cn/simple连接数据库时需要注意协议版本的变化。较新的Neo4j默认使用Bolt协议而旧版可能使用HTTP协议。以下是两种连接方式的对比连接方式协议示例代码适用版本Bolt协议bolt://Graph(bolt://localhost:7687, auth(neo4j, password))Neo4j 4.0HTTP协议http://Graph(http://localhost:7474, usernameneo4j, passwordpassword)Neo4j 3.x提示生产环境务必修改默认密码本文示例为演示方便使用简单密码首次连接成功后建议执行健康检查from py2neo import Graph graph Graph(bolt://localhost:7687, auth(neo4j, 123456)) print(fNeo4j版本: {graph.version}) print(f节点数量: {graph.run(MATCH (n) RETURN count(n)).evaluate()})2. 图数据建模实战2.1 武侠人物节点创建在Neo4j中节点(Node)是图数据的基本单元。让我们用金庸武侠人物构建第一个节点from py2neo import Node # 创建带标签和属性的节点 zhang_wuji Node(人物, 主角, name张无忌, skill九阳神功, faction明教) zhao_min Node(人物, 女主角, name赵敏, title绍敏郡主) xie_xun Node(人物, 配角, name谢逊, nickname金毛狮王) # 批量创建节点 nodes [zhang_wuji, zhao_min, xie_xun] graph.create(Subgraph(nodesnodes))节点标签系统就像数据库中的表可以支持以下查询模式MATCH (n:人物) RETURN n- 查询所有人物MATCH (n:主角) RETURN n- 查询所有主角MATCH (n:人物:主角) RETURN n- 查询既是人物又是主角的节点2.2 复杂关系网络构建关系(Relationship)是图数据库的灵魂。武侠世界中的人物关系尤为丰富from py2neo import Relationship # 建立基础关系 relations [ Relationship(zhang_wuji, 爱慕, zhao_min), Relationship(zhao_min, 设计, zhang_wuji), Relationship(xie_xun, 义父, zhang_wuji), Relationship(zhang_wuji, 师徒, xie_xun) ] # 添加关系属性 fight_rel Relationship(zhao_min, 交手, zhang_wuji) fight_rel[结果] 平手 fight_rel[地点] 绿柳庄 relations.append(fight_rel) graph.create(Subgraph(relationshipsrelations))关系类型可以构成丰富的语义网络张无忌 -[爱慕]- 赵敏 张无忌 -[设计]- 赵敏 谢逊 -[义父]- 张无忌 张无忌 -[师徒]- 谢逊 赵敏 -[交手]- 张无忌2.3 路径查询与遍历路径(Path)是节点和关系的组合序列非常适合分析人物关联from py2neo import Path # 构建复杂路径 path Path(zhao_min, 对手, zhang_wuji, Relationship(xie_xun, 保护, zhang_wuji), xie_xun) graph.create(path) # 查找两人之间的最短路径 query MATCH pathshortestPath( (zhao:人物 {name:赵敏})-[*]-(xie:人物 {name:谢逊}) ) RETURN path result graph.run(query).to_data_frame()路径分析可以回答诸如赵敏要通过多少人才能影响明教核心层这类问题。3. 高级查询技巧3.1 模式匹配查询Py2neo提供了多种查询构建方式以下是最常用的三种模式1. Cypher直接执行result graph.run( MATCH (n:人物)-[r]-(m) WHERE n.name CONTAINS 张 RETURN n.name, type(r), m.name ).data()2. 节点匹配器(NodeMatcher)from py2neo import NodeMatcher matcher NodeMatcher(graph) # 查找所有会九阳神功的人物 heroes matcher.match(人物, skill九阳神功).all() # 查找名字包含张的人物 zhangs matcher.match(人物).where(_.name CONTAINS 张)3. 关系匹配器(RelationshipMatcher)from py2neo import RelationshipMatcher rel_matcher RelationshipMatcher(graph) # 查找所有爱慕关系 loves rel_matcher.match(r_type爱慕) # 查找赵敏发起的所有关系 zhao_relations rel_matcher.match(nodes(zhao_min, None))3.2 事务处理对于关键操作应该使用事务保证数据一致性tx graph.begin() try: # 创建新节点 zhang_sanfeng Node(人物, name张三丰) tx.create(zhang_sanfeng) # 建立关系 tx.create(Relationship(zhang_wuji, 师公, zhang_sanfeng)) # 更新属性 zhang_wuji[skill] 九阳神功,乾坤大挪移,太极拳 tx.push(zhang_wuji) tx.commit() except Exception as e: print(f操作失败: {e}) tx.rollback()3.3 批量操作优化当需要处理大量数据时批量操作能显著提升性能from py2neo import Subgraph # 准备批量数据 persons [ Node(人物, name周芷若, faction峨眉), Node(人物, name小昭, faction明教), Node(人物, name殷离, nickname蛛儿) ] relations [ Relationship(persons[0], 情敌, zhao_min), Relationship(persons[1], 侍女, zhang_wuji), Relationship(persons[2], 表妹, zhang_wuji) ] # 一次性提交 subgraph Subgraph(nodespersons, relationshipsrelations) graph.create(subgraph)4. 实战武侠知识图谱分析4.1 社交影响力分析通过图算法计算人物中心度# 计算度中心度 degree_query MATCH (n:人物) RETURN n.name AS name, size((n)--()) AS degree ORDER BY degree DESC LIMIT 5 print(社交达人TOP5:) for record in graph.run(degree_query): print(f{record[name]}: {record[degree]}度连接)4.2 派系关系可视化使用Cypher生成ECharts可用的关系数据faction_query MATCH (a:人物)-[r]-(b:人物) RETURN { source: a.name, target: b.name, relation: type(r), lineStyle: { width: 2, curveness: 0.2 } } AS links links [record[links] for record in graph.run(faction_query)]4.3 智能问答实现基于图数据库实现简单的自然语言查询def answer_question(question): if 师父 in question: name question.split(的)[0] query f MATCH (n:人物 {{name:{name}}})-[:师徒]-(m) RETURN m.name AS master result graph.run(query).evaluate() return f{name}的师父是{result} if result else 未找到师父信息 elif 关系 in question: names [n.strip() for n in question.replace(的关系,).split(和)] query f MATCH pathshortestPath((a {{name:{names[0]}}})-[*..5]-(b {{name:{names[1]}}})) RETURN [r IN relationships(path) | type(r)] AS rels result graph.run(query).evaluate() return → .join(result) if result else 未找到直接关系在实际项目中这样的知识图谱可以支持从张无忌的义父是谁到找出正邪两派的关键联络人等各种复杂查询。

更多文章