19.1 Neo4j简介与环境准备 #
- Neo4j:全球最流行的图数据库,适合存储和分析复杂关系数据。
- Python驱动:官方推荐
neo4j包,支持Neo4j 4.x/5.x。
19.2 安装Neo4j与Python驱动 #
# 安装Python驱动
pip install neo4j19.3 Python连接Neo4j数据库 #
详细讲解: 本节演示如何使用Python官方驱动连接本地Neo4j数据库。首先导入驱动包,然后设置连接参数(地址、用户名、密码),最后通过with语句创建连接和会话,执行一条简单的Cypher查询(RETURN 1 AS test),并输出结果。推荐用with语句自动管理资源,避免连接泄漏。
# 导入Neo4j官方驱动包
from neo4j import GraphDatabase
# 设置连接地址,bolt协议,默认端口7687
uri = "bolt://localhost:7687"
# 设置用户名
user = "neo4j"
# 设置密码
password = "12345678"
# 创建驱动对象,推荐用with语句自动关闭连接
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
# 创建会话对象,同样用with语句自动关闭
with driver.session() as session:
# 执行Cypher查询,返回结果对象
result = session.run("RETURN 1 AS test")
# 取出结果中的test字段并打印
print(result.single()["test"])19.4 节点的创建与批量创建 #
19.4.1 单个节点创建 #
def create_node(tx, label, properties):
query = f"CREATE (n:{label} $props) RETURN n"
result = tx.run(query, props=properties)
return result.single()[0]
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
node = session.execute_write(create_node, "Person", {"name": "Alice", "age": 30, "occupation": "Engineer"})
print("Created node:", node)19.4.2 批量创建节点 #
def create_nodes(tx, data):
query = "UNWIND $data AS item CREATE (n:Person {name: item.name, age: item.age})"
tx.run(query, data=data)
persons = [
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35},
{"name": "Diana", "age": 28}
]
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
session.execute_write(create_nodes, persons)
print("Created 3 nodes")19.5 关系的创建 #
def create_relationship(tx, from_name, to_name, rel_type, properties=None):
query = (
"MATCH (a:Person {name: $from_name}), (b:Person {name: $to_name}) "
f"CREATE (a)-[r:{rel_type}]->(b) "
"SET r += $props "
"RETURN r"
)
props = properties if properties else {}
result = tx.run(query, from_name=from_name, to_name=to_name, props=props)
return result.single()[0]
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
relationship = session.execute_write(create_relationship, "Alice", "Bob", "KNOWS", {"since": 2020})
print("Created relationship:", relationship)19.6 节点与关系的查询 #
19.6.1 查询所有Person节点 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
result = session.run("MATCH (n:Person) RETURN n.name, n.age")
for record in result:
print(record["n.name"], record["n.age"])19.6.2 查询关系 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
result = session.run("MATCH (a:Person)-[r:KNOWS]->(b:Person) RETURN a.name, b.name, r.since")
for record in result:
print(f"{record['a.name']} knows {record['b.name']} since {record['r.since']}")19.7 属性操作(增删改查) #
19.7.1 修改属性 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
session.run("MATCH (n:Person {name: 'Alice'}) SET n.city = 'Beijing'")19.7.2 删除属性 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
session.run("MATCH (n:Person {name: 'Alice'}) REMOVE n.city")19.7.3 删除节点和关系 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
session.run("MATCH (n:Person {name: 'Diana'}) DETACH DELETE n")19.8 复杂查询与聚合 #
19.8.1 聚合统计 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
result = session.run("MATCH (n:Person) RETURN count(n) AS total")
print("Total persons:", result.single()["total"])19.8.2 分组统计 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
result = session.run("MATCH (n:Person) RETURN n.age, count(*) AS num")
for record in result:
print(f"Age {record['n.age']}: {record['num']}")19.9 时间类型与APOC扩展用法 #
19.9.1 创建带时间的事件节点 #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
session.run("CREATE (:Event {name: '会议', time: datetime()})")
session.run("CREATE (:Event {name: '发布会', time: datetime('2024-06-01T09:00:00')})")19.9.2 查询并格式化时间(APOC) #
with GraphDatabase.driver(uri, auth=(user, password)) as driver:
with driver.session() as session:
result = session.run("""
MATCH (e:Event)
RETURN e.name, apoc.temporal.format(e.time, 'yyyy-MM-dd HH:mm') AS time
LIMIT 5
""")
for record in result:
print(f"{record['e.name']} at {record['time']}")19.10 最佳实践与常见问题 #
- 用with语句管理连接,避免资源泄漏
- 参数化查询,防止注入
- 批量操作用UNWIND提升效率
- 注意Neo4j与Python时间格式的差异
- 遇到连接/认证问题,检查端口、用户名、密码、APOC插件是否启用