Neo4j 与 Python 入门
在本篇博文中,我们将通过构建一个 Python 应用程序,来突显 Neo4j 的优势,并展示 Python 开发者如何利用图数据库解决复杂的数据问题。
但在开始编写代码之前,让我们先看看为什么 Python 开发者会首先考虑使用图数据库。

为什么 Python 开发者会选择图数据库?
图数据库的诞生,源于对建模和查询复杂、高度连接的数据领域的需求,这些领域在传统的表格或文档结构中难以有效地表示。Neo4j 使用属性图模型(节点和关系,每种都具有各自的属性),以一种直观、类似白板绘图的方式来表达数据。
在 Python 中,使用关系型数据库或 NoSQL 数据库通常需要转换数据结构,以适应那些并非为处理复杂关系而设计的后端系统。使用图数据库,Python 开发者可以原生方式对现实世界中的网络、层级结构和依赖关系进行建模,并使用 Cypher 高效地查询它们。
想比较语言特性是如何从 Python 2 演进到 Python 3 的吗?想追踪跨版本软件包之间的依赖关系吗?想在欺诈交易网络中查找路径,或推荐好友的朋友吗?这些领域正是图数据库的用武之地。
此外,Python 灵活的数据建模方式(使用字典、对象或数据类)与图数据的结构方式非常契合。
创建项目
让我们构建一个简单的应用程序,连接到 Neo4j 实例并从示例数据集中查询有关书籍和作者的数据。
先决条件
你需要
- Python 3.8+
- neo4j Python 包(使用 pip install neo4j 进行安装)
- 访问 Neo4j 实例的权限
在本教程中,我们将使用 Neo4j 托管的演示数据库
浏览器:https://demo.neo4jlabs.com:7473/browser/
凭据
- URI: neo4j+s://demo.neo4jlabs.com
- 用户名: goodreads
- 密码: goodreads
- 数据库: goodreads
您可以通过在浏览器中运行此 Cypher 查询来验证数据集
CALL db.schema.visualization;Code language: Shell Session (shell)

或者在以下地址启动您自己的免费 Neo4j Aura 实例:https://console.neo4j.io/
项目结构
让我们采用一种简单的 Python 布局
neo4j-python-tutorial/
├── app.py
├── .env
└── requirements.txt
安装 Neo4j Python 驱动程序
在 requirements.txt 中
neo4j==5.28.1
python-dotenv==1.1.0Code language: Shell Session (shell)
创建并运行虚拟环境
python -m venv venv
source venv/bin/activateCode language: Shell Session (shell)
然后安装依赖项
pip install -r requirements.txtCode language: Shell Session (shell)
配置 Neo4j 凭据
在 .env 中
NEO4J_URI = "neo4j+s://demo.neo4jlabs.com"
NEO4J_USERNAME = "goodreads"
NEO4J_PASSWORD = "goodreads"
NEO4J_DATABASE = "goodreads"Code language: Shell Session (shell)
使用 Neo4j 进行连接和查询
创建 app.py
import os
from dotenv import load_dotenv
load_dotenv()
from neo4j import GraphDatabase
# Initialize the Neo4j driver
driver = GraphDatabase.driver(
os.getenv('NEO4J_URI'),
auth=(
os.getenv('NEO4J_USERNAME'),
os.getenv('NEO4J_PASSWORD')
)
)
# Verify the connection
driver.verify_connectivity()
# Define the query
cypher_query = """
MATCH (r:Review)-[:WRITTEN_FOR]->(:Book)<-[:AUTHORED]-(a:Author)
WHERE a.name = $name
RETURN r {.text, .rating}
ORDER BY r.rating DESC
LIMIT 10
"""
# Execute the query with a parameter
records, summary, keys = driver.execute_query(
cypher_query,
name="Jennifer Weiner"
)
# Parse the result
for record in records:
# Print the return values
print(f"record: {record}")
# Close the driver
driver.close()Code language: Python (python)
运行
python run app.pyCode language: Shell Session (shell)
示例输出(已修剪)
<Record r={'text': 'Addie Downs thought her and Valerie Adler would be best friends forever.But when Valerie becomes part of the popular crowd and Addie becomes the scapegoat of her classmates. The friendship kind of grows apart.Flash forward fifteen years. Valerie has found a measure of fame as the local weather girl.Addie lives alone in her parents old house in Pleasant Ridge IL. and cares for her troubled brother . She is still hoping and trying to meet her own prince charming so she has turned to internet dating.She has just returned home from bad date number 6 when there is a knock on her door .There stands Valerie with blood on her coat sleeve and a terrified look on her face. She tells Addie something horrible has happened and your the only one who can help. Its a hilarious adventure , a story about loyalty and betrayal, family history and small town secrets. Its about finding love where you least expect it and living through tragedy. And the ties that keep best friends together.', 'rating': 5}>
…Code language: Shell Session (shell)
查询解释
代码的关键部分是 cypher_query 和 driver.execute_query() 函数。
Cypher 是用于 Neo4j 数据库读取和写入数据的主要查询语言。MATCH (r:Review)-[:WRITTEN_FOR]->(:Book)<-[:AUTHORED]-(a:Author) 部分指定了所存储数据的模式或子图。只有通过上述中间关系和节点链连接到作者的评论(Review)才会被返回。例如,尚未撰写过书籍的作者将不会出现在返回的数据中。
WHERE a.name = $name 是一个过滤子句,只有 name 属性与命名参数 $name 的值匹配的作者才会包含在结果中。或者,也可以硬编码一个值,例如 WHERE a.name = “Rachel Roberts”。
return 语句 RETURN r {.text, .rating} 指定仅返回匹配评论的 text 和 rating 属性。如果仅使用 RETURN r,将返回与找到的评论相关联的所有数据。此特定数据集包含 .embeddings 属性中的向量嵌入,若全部返回会导致输出非常冗长。
最后,ORDER BY r.rating DESC LIMIT 10 将按评论的 .rating 属性对结果进行排序,从高到低排列。limit 语句强制仅返回前 10 条评论。
execute_query() 函数至少需要 1 个参数,即要运行的 Cypher 查询。但是,如果使用了命名参数,则需要连同值来源一起传入。
records, summary, keys = driver.execute_query(
cypher_query,
name="Jennifer Weiner"
)Code language: Python (python)
该函数返回一个包含记录的元组(作为列表)、一个摘要对象以及每个记录中找到的键列表。有关此查询函数的更多详细信息,请参阅此处文档。
后续步骤
在此基础上,您可以
- 添加 Flask 或 FastAPI 将其转换为 Web API
- 使用 neomodel 进行更高级的建模


