目录
Graph Databases: Books, readers, and borrowing records serve as nodes, with edges representing data relationships such as borrowing connections and collection associations
1 代码示例
图书、读者、借阅记录 → 借阅关系、收藏关系。
1.1 创建节点和关系
// 清除现有数据(仅用于示例)
MATCH (n) DETACH DELETE n;
// 创建图书节点
CREATE (b1:Book {book_id: "B001", title: "Neo4j图数据库实战", author: "张明", publisher: "科技出版社", publish_year: 2022, isbn: "9787123456789", category: "计算机科学"})
CREATE (b2:Book {book_id: "B002", title: "Cypher查询语言指南", author: "李华", publisher: "编程出版社", publish_year: 2021, isbn: "9787234567890", category: "计算机科学"})
CREATE (b3:Book {book_id: "B003", title: "百年孤独", author: "加西亚·马尔克斯", publisher: "文学出版社", publish_year: 1967, isbn: "9787345678901", category: "文学"})
CREATE (b4:Book {book_id: "B004", title: "人类简史", author: "尤瓦尔·赫拉利", publisher: "历史出版社", publish_year: 2011, isbn: "9787456789012", category: "历史"})
// 创建读者节点
CREATE (r1:Reader {reader_id: "R001", name: "王小明", gender: "男", age: 25, phone: "13800138001", email: "wang@example.com", register_date: date("2022-01-15")})
CREATE (r2:Reader {reader_id: "R002", name: "张小红", gender: "女", age: 30, phone: "13900139002", email: "zhang@example.com", register_date: date("2021-11-20")})
CREATE (r3:Reader {reader_id: "R003", name: "李四", gender: "男", age: 22, phone: "13700137003", email: "li@example.com", register_date: date("2023-03-10")})
// 创建图书馆员节点
CREATE (l1:Librarian {staff_id: "L001", name: "赵管理员", position: "高级馆员", department: "借阅部"})
CREATE (l2:Librarian {staff_id: "L002", name: "钱管理员", position: "初级馆员", department: "采编部"})
// 创建借阅关系
MATCH (r:Reader {reader_id: "R001"}), (b:Book {book_id: "B001"})
CREATE (r)-[br1:BORROWED {borrow_id: "BR001", borrow_date: date("2023-05-10"), due_date: date("2023-06-10"), return_date: date("2023-06-05"), status: "已归还"}]->(b)
MATCH (r:Reader {reader_id: "R001"}), (b:Book {book_id: "B002"})
CREATE (r)-[br2:BORROWED {borrow_id: "BR002", borrow_date: date("2023-05-15"), due_date: date("2023-06-15"), return_date: null, status: "借出中"}]->(b)
MATCH (r:Reader {reader_id: "R002"}), (b:Book {book_id: "B003"})
CREATE (r)-[br3:BORROWED {borrow_id: "BR003", borrow_date: date("2023-04-20"), due_date: date("2023-05-20"), return_date: date("2023-05-18"), status: "已归还"}]->(b)
MATCH (r:Reader {reader_id: "R003"}), (b:Book {book_id: "B004"})
CREATE (r)-[br4:BORROWED {borrow_id: "BR004", borrow_date: date("2023-06-01"), due_date: date("2023-07-01"), return_date: null, status: "借出中"}]->(b)
// 创建收藏关系
MATCH (r:Reader {reader_id: "R001"}), (b:Book {book_id: "B003"})
CREATE (r)-[f1:FAVORITE {add_date: date("2023-03-15"), note: "经典文学作品"}]->(b)
MATCH (r:Reader {reader_id: "R002"}), (b:Book {book_id: "B001"})
CREATE (r)-[f2:FAVORITE {add_date: date("2023-02-10"), note: "学习图数据库"}]->(b)
// 创建管理关系(馆员管理图书)
MATCH (l:Librarian {staff_id: "L001"}), (b:Book {book_id: "B001"})
CREATE (l)-[m1:MANAGES {action: "编目", date: date("2022-02-01")}]->(b)
MATCH (l:Librarian {staff_id: "L002"}), (b:Book {book_id: "B002"})
CREATE (l)-[m2:MANAGES {action: "采购", date: date("2021-12-15")}]->(b)
1.2 查询
1.2.1 基本查询
// 查询所有图书
MATCH (b:Book)
RETURN b.book_id AS book_id, b.title AS title, b.author AS author
ORDER BY b.title;
// 查询特定读者借阅的所有图书
MATCH (r:Reader {reader_id: "R001"})-[:BORROWED]->(b:Book)
RETURN r.name AS reader, b.title AS book_title, b.author AS author;
// 查询当前借出中的图书
MATCH (r:Reader)-[br:BORROWED {status: "借出中"}]->(b:Book)
RETURN r.name AS reader, b.title AS book, br.borrow_date AS borrow_date, br.due_date AS due_date;
1.2.2 复杂查询
// 查询读者及其借阅历史(包括已归还和借出中的)
MATCH (r:Reader)-[br:BORROWED]->(b:Book)
RETURN r.name AS reader,
b.title AS book,
br.borrow_date AS borrow_date,
br.due_date AS due_date,
br.return_date AS return_date,
br.status AS status
ORDER BY r.name, br.borrow_date DESC;
// 查询图书的受欢迎程度(按借阅次数排序)
MATCH (b:Book)<-[br:BORROWED]-()
RETURN b.title AS book, count(br) AS borrow_count
ORDER BY borrow_count DESC;
// 查询读者收藏但尚未借阅的图书
MATCH (r:Reader {reader_id: "R001"})-[:FAVORITE]->(b:Book)
WHERE NOT (r)-[:BORROWED]->(b)
RETURN b.title AS favorite_book, b.author AS author;
// 查询逾期未还的图书(假设今天是2023-06-20)
MATCH (r:Reader)-[br:BORROWED {status: "借出中"}]->(b:Book)
WHERE date("2023-06-20") > br.due_date
RETURN r.name AS reader, r.phone AS phone, b.title AS book, br.due_date AS due_date;
// 路径查询
// 查找两本相关图书的共同读者
MATCH (b1:Book {book_id: "B001"})<-[:BORROWED]-(r:Reader)-[:BORROWED]->(b2:Book {book_id: "B003"})
RETURN r.name AS reader, b1.title AS book1, b2.title AS book2;
// 查找读者可能感兴趣的图书(基于其他借阅过相同图书的读者的借阅记录)
MATCH (target:Reader {reader_id: "R001"})-[:BORROWED]->(b:Book)<-[:BORROWED]-(other:Reader)-[:BORROWED]->(recommendation:Book)
WHERE NOT (target)-[:BORROWED]->(recommendation)
RETURN DISTINCT recommendation.title AS recommended_book,
recommendation.author AS author,
count(*) AS recommendation_score
ORDER BY recommendation_score DESC
LIMIT 5;
1.2.3 统计查询
// 按类别统计图书数量
MATCH (b:Book)
RETURN b.category AS category, count(*) AS book_count
ORDER BY book_count DESC;
// 统计各年龄段的读者借阅量
MATCH (r:Reader)-[br:BORROWED]->(b:Book)
RETURN
CASE
WHEN r.age < 20 THEN '20岁以下'
WHEN r.age >= 20 AND r.age < 30 THEN '20-29岁'
WHEN r.age >= 30 AND r.age < 40 THEN '30-39岁'
ELSE '40岁及以上'
END AS age_group,
count(br) AS borrow_count
ORDER BY age_group;
// 每月借阅量统计
MATCH ()-[br:BORROWED]->()
RETURN
br.borrow_date.year AS year,
br.borrow_date.month AS month,
count(*) AS borrow_count
ORDER BY year, month;
1.3 更新和删除
// 更新图书信息
MATCH (b:Book {book_id: "B001"})
SET b.category = "数据库技术"
RETURN b;
// 添加新借阅记录
MATCH (r:Reader {reader_id: "R002"}), (b:Book {book_id: "B004"})
CREATE (r)-[br:BORROWED {borrow_id: "BR005", borrow_date: date("2023-06-18"), due_date: date("2023-07-18"), return_date: null, status: "借出中"}]->(b)
RETURN r.name, b.title, br.borrow_date;
// 更新借阅状态为已归还
MATCH (r:Reader {reader_id: "R001"})-[br:BORROWED {borrow_id: "BR002"}]->(b:Book)
SET br.return_date = date("2023-06-12"), br.status = "已归还"
RETURN r.name, b.title, br.borrow_date, br.return_date;
// 删除收藏关系
MATCH (r:Reader {reader_id: "R002"})-[f:FAVORITE]->(b:Book {book_id: "B001"})
DELETE f
RETURN r.name, b.title;
1.4 可视化
import matplotlib.pyplot as plt
import networkx as nx
# 设置中文字体支持和高清显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Noto Sans CJK JP']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.dpi'] = 300 # 提高默认DPI
def create_high_quality_library_graph():
# 创建图形对象
G = nx.DiGraph()
# 定义节点颜色和大小(适当增大以便清晰显示)
node_style = {
'Book': {'color': '#FF6B6B', 'size': 800},
'Reader': {'color': '#4ECDC4', 'size': 800},
'Librarian': {'color': '#45B7D1', 'size': 800}
}
# 添加节点(图书)
books = [
("B001", "Neo4j图数据库实战"),
("B002", "Cypher查询语言指南"),
("B003", "百年孤独"),
("B004", "人类简史")
]
for book_id, title in books:
G.add_node(book_id, type='Book', label=f"{book_id}\n{title}",
color=node_style['Book']['color'], size=node_style['Book']['size'])
# 添加节点(读者)
readers = [
("R001", "王小明"),
("R002", "张小红"),
("R003", "李四")
]
for reader_id, name in readers:
G.add_node(reader_id, type='Reader', label=f"{reader_id}\n{name}",
color=node_style['Reader']['color'], size=node_style['Reader']['size'])
# 添加节点(图书馆员)
librarians = [
("L001", "赵管理员"),
("L002", "钱管理员")
]
for staff_id, name in librarians:
G.add_node(staff_id, type='Librarian', label=f"{staff_id}\n{name}",
color=node_style['Librarian']['color'], size=node_style['Librarian']['size'])
# 添加边(借阅关系)
borrow_relations = [
("R001", "B001", "已归还"),
("R001", "B002", "借出中"),
("R002", "B003", "已归还"),
("R003", "B004", "借出中")
]
edge_styles = {
"已归还": {"style": "-", "color": "#95E1D3", "width": 2.0}, # 加粗线条
"借出中": {"style": "--", "color": "#F38BA8", "width": 2.0}
}
for reader, book, status in borrow_relations:
style = edge_styles[status]
G.add_edge(reader, book, relation='BORROWED', status=status,
style=style["style"], color=style["color"], width=style["width"])
# 添加边(收藏关系)
favorite_relations = [
("R001", "B003"),
("R002", "B001")
]
for reader, book in favorite_relations:
G.add_edge(reader, book, relation='FAVORITE', style="-.", color="#FCE38A", width=2.0)
# 添加边(管理关系)
manage_relations = [
("L001", "B001"),
("L002", "B002")
]
for librarian, book in manage_relations:
G.add_edge(librarian, book, relation='MANAGES', style=":", color="#A8DADC", width=2.0)
return G
# 创建图
G = create_high_quality_library_graph()
# 创建高分辨率图形
fig = plt.figure(figsize=(12, 8), dpi=300) # 增大尺寸并设置高DPI
# 设置紧凑的位置布局
pos = {
# 图书节点 - 上层
"B001": (2, 6),
"B002": (4, 6),
"B003": (6, 6),
"B004": (8, 6),
# 读者节点 - 中层
"R001": (1, 3),
"R002": (3, 3),
"R003": (5, 3),
# 图书馆员节点 - 下层
"L001": (7, 3),
"L002": (9, 3)
}
# 获取节点属性
node_colors = [G.nodes[node]['color'] for node in G.nodes()]
node_sizes = [G.nodes[node]['size'] for node in G.nodes()]
labels = {node: G.nodes[node]['label'] for node in G.nodes()}
# 绘制节点(增加边框和透明度)
nx.draw_networkx_nodes(G, pos, node_color=node_colors, node_size=node_sizes,
alpha=0.95, edgecolors='black', linewidths=1.5)
# 绘制边(加粗线条,提高可见性)
for u, v, data in G.edges(data=True):
nx.draw_networkx_edges(G, pos, edgelist=[(u, v)],
edge_color=data['color'],
style=data['style'],
width=data['width'],
arrows=True,
arrowstyle='-|>', # 更清晰的箭头样式
arrowsize=20, # 增大箭头
alpha=0.9)
# 添加节点标签(增大字体,提高可读性)
nx.draw_networkx_labels(G, pos, labels, font_size=10, font_family='SimHei',
font_weight='bold', verticalalignment='center')
# 创建清晰的图例
legend_elements = [
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#FF6B6B', markersize=12, label='图书', markeredgewidth=1.5),
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#4ECDC4', markersize=12, label='读者', markeredgewidth=1.5),
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#45B7D1', markersize=12, label='图书馆员', markeredgewidth=1.5),
plt.Line2D([0], [0], color='#95E1D3', lw=2.0, label='借阅(已归还)'),
plt.Line2D([0], [0], color='#F38BA8', lw=2.0, linestyle='--', label='借阅(借出中)'),
plt.Line2D([0], [0], color='#FCE38A', lw=2.0, linestyle='-.', label='收藏'),
plt.Line2D([0], [0], color='#A8DADC', lw=2.0, linestyle=':', label='管理')
]
# 创建清晰的图例
plt.legend(handles=legend_elements, loc='upper center', bbox_to_anchor=(0.5, -0.05),
ncol=4, fontsize=10, frameon=True, fancybox=True, shadow=True,
framealpha=0.9)
plt.title('图书馆图数据库可视化示意图', fontsize=14, pad=15, fontweight='bold')
plt.axis('off')
# 设置合适的边界
plt.xlim(0, 10)
plt.ylim(2, 7)
# 调整布局
plt.tight_layout()
# 保存为高质量PNG文件(适合Word文档)
high_quality_path = 'high_quality_library_graph.png'
plt.savefig(high_quality_path, dpi=600, bbox_inches='tight', facecolor='white',
pad_inches=0.2, transparent=False,
format='png') # 明确指定PNG格式
# 同时保存为PDF格式(矢量图,在Word中更清晰)
pdf_path = 'library_graph.pdf'
plt.savefig(pdf_path, bbox_inches='tight', facecolor='white',
format='pdf')
print(f"高质量PNG图片已保存为: {high_quality_path}")
print(f"矢量PDF图片已保存为: {pdf_path}")
print("图片参数:")
print(f"- 尺寸: 12×8 英寸")
print(f"- 分辨率: 600 DPI")
print(f"- 节点大小: 800")
print(f"- 字体大小: 10-14pt")
print(f"- 线条宽度: 2.0")
plt.show()
运行结果如下:

另附其他可视图。

图书类别分布相对均衡,涵盖计算机科学、文学、历史等多个领域
读者主要集中在20-29岁年龄段
借阅状态分布均匀,体现了良好的图书流通性

关系网络密度反映了图书馆系统中各种关系的丰富程度:
借阅关系是最主要的关系类型
收藏关系和管理关系补充了系统的功能性

与传统关系型数据库相比,图数据库在处理复杂关系方面具有明显优势:
关联查询性能:图数据库得分9分,远超传统关系型数据库的4分
数据建模灵活性:图数据库得分为9分,传统数据库仅为3分
复杂关系表达:图数据库完美支持复杂关系表达(9分)
实时推荐能力:图数据库具备强大的实时推荐能力(9分)
这种可视化展示充分体现了图数据库在处理图书馆这类高度关联数据时的优势,能够直观展现实体间的复杂关系,并提供高效的查询性能。
2 欢迎纠错
欢迎纠错,随时更新。
联系方式:评论、私信,或 企鹅 :179 0042 182 。
码字不易,如觉得还可以,请给个免费的 zan 和 soucang ,让我有动力继续写下去。
3 免费爬虫
https://affiliate
.bazhuayu
.com
/M8lKUC
4 论文写作/Python 学习智能体
https://chatglm.cn/share/WF2C5ree
-
- 以下关于 Markdown 编辑器
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
++ 新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
++ 功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
++ 合理的创建标题,有助于目录的生成
直接输入1次+,并按下space后,将生成1级标题。
输入2次+,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。
++ 如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
++ 插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
++ 如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.
// An highlighted block
var foo = 'bar';
++ 生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
++ 创建一个表格
一个简单的表格是这么创建的:
| 项目 | Value |
|---|---|
| 电脑 | $1600 |
| 手机 | $12 |
| 导管 | $1 |
+++ 设定内容居中、居左、居右
使用:---------:居中
使用:----------居左
使用----------:居右
| 第一列 | 第二列 | 第三列 |
|---|---|---|
| 第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
+++ SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
| TYPE | ASCII | HTML |
|---|---|---|
| Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
| Quotes | "Isn't this fun?" | “Isn’t this fun?” |
| Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
++ 创建一个自定义列表
Markdown
: Text-to-HTML conversion tool
-
Authors
- John
- Luke
++ 如何创建一个注脚
一个具有注脚的文本。2
++ 注释也是必不可少的
Markdown将文本转换为 HTML。
++ KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
++ 新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
++ UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
++ FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
++ 导出与导入
+++ 导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
+++ 导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎

被折叠的 条评论
为什么被折叠?



