calibre 虚拟书库(Virtual libraries)完全指南:用搜索将大型书库优雅分区
虚拟书库(Virtual library)是 calibre 电子书管理器提供的书库分区机制:它通过一条搜索表达式,让 calibre 只在主界面中展示原书库的一个子集,同时标签浏览器(Tag browser)也随之收缩到该子集范围内,效果等同于“当前书库只包含这批书”。本指南以 manual/virtual_libraries.rst 为骨架,结合 搜索接口说明 与 保存搜索说明 以及 GUI 与数据库层的源码实现,系统讲解虚拟书库的创建、管理、搜索语法、附加限制与内容服务器中的联动用法,读完你就能用一套表达式把数千本书按作者、标签、评分、阅读状态等维度组织成可随时切换的子书库。
为什么用虚拟书库而不是拆分成多个书库
当一个书库包含大量书籍时,最直观的想法是按类别拆成多个独立书库。但 calibre 官方文档明确指出,虚拟书库是分割大型收藏的首选方式,原因有二:
- 随时回到全集:虚拟书库不会删除或移动任何书,切换回完整书库只需点击
<None>条目,即可继续在整个收藏中检索。 - 完整检索不可替代:calibre 无法同时跨多个独立书库搜索;而虚拟书库只是同一个书库上的“视图”,任何搜索都天然覆盖全部书籍。
虚拟书库也不等同于一次普通搜索。普通搜索(Search bar 输入表达式)只过滤书籍列表;而虚拟书库除了过滤书籍列表,还会同步过滤左侧 标签浏览器(Tag browser)——标签、作者、系列、出版社等条目只会显示来自虚拟书库内书籍的值。从用户视角看,虚拟书库表现得“好像真实书库只有这些书”。这一行为在源码中也有体现:书籍列表与标签浏览器都基于受限后的书 ID 集合渲染,相关实现在 src/calibre/gui2/search_restriction_mixin.py 的 apply_virtual_library 等逻辑中完成。
创建虚拟书库
方式一:通过作者链接快速创建
点击搜索栏左侧的 Virtual library(虚拟书库) 按钮,选择 Create Virtual library(创建虚拟书库):
在弹出的对话框中点击 Authors(作者) 链接,选择一位作者并确认,创建对话框即自动填好对应搜索表达式,点击 OK 后新的虚拟书库被创建并自动切换,书库中“只剩下”该作者的书。随时可再次点击虚拟书库按钮,选择 <None> 回到完整书库。
方式二:用任意搜索表达式创建
虚拟书库的本质是一条搜索,因此你可以用任何合法的 calibre 搜索作为其定义:
- 在搜索栏输入搜索表达式,或借助标签浏览器逐步构建搜索;
- 确认返回结果符合预期后,点击 Virtual library 按钮;
- 选择 Create library,为新的虚拟书库命名。
虚拟书库即基于这条搜索创建。搜索语法的完整能力可参考 搜索接口(The search interface)。
实用的虚拟书库示例
以下表达式均直接来自官方文档,可直接复制使用:
| 用途 | 搜索表达式 |
|---|---|
| 最近一天添加的书 | date:>1daysago |
| 最近一个月添加的书 | date:>30daysago |
| 评分为 5 星的书 | rating:5 |
| 评分至少 4 星的书 | rating:>=4 |
| 无评分的书 | rating:false |
| Fetch News 下载的期刊 | tags:=News and author:=calibre |
| 无标签的书 | tags:false |
| 无封面的书 | cover:false |
这些表达式展示了 calibre 搜索系统对日期、数值比较(>=)以及布尔/空值判定(false)的支持。从源码实现看,搜索解析与求值位于 src/calibre/db/search.py,其中 SearchQueryParser 负责解析这类表达式,get_matches 把解析结果映射为匹配的书 ID 集合;虚拟书库的“匹配”正是这一机制的复用。
虚拟书库的存储与底层求值
在数据层,虚拟书库以“名称 → 搜索表达式”的字典形式保存在 calibre 的偏好设置键 virtual_libraries 中。创建/编辑时,GUI 调用 add_virtual_library 写入该键并清空搜索缓存、刷新书籍模型,见 src/calibre/gui2/search_restriction_mixin.py 的 add_virtual_library 与 do_create_edit。
读取虚拟书库中的书籍则通过数据库层 API 完成,见 src/calibre/db/cache.py:
def books_in_virtual_library(self, vl, search_restriction=None, virtual_fields=None):
"Return the set of books in the specified virtual library"
vl = self._pref('virtual_libraries', {}).get(vl) if vl else None
if not vl and not search_restriction:
return self.all_book_ids()
# We utilize the search restriction cache to speed this up
srch = partial(self._search, virtual_fields=virtual_fields)
if vl:
if search_restriction:
return frozenset(srch('', vl) & srch('', search_restriction))
return frozenset(srch('', vl))
return frozenset(srch('', search_restriction))
这段代码揭示了几点实现事实:
- 虚拟书库的求值本质是对表达式执行一次搜索,并复用“搜索限制缓存”(search restriction cache)加速重复查询;
- 若同时存在附加限制(
search_restriction),则取两个结果集的交集(&),这正是“附加限制”功能的底层机制; - 同文件还提供
number_of_books_in_virtual_library,用于统计虚拟书库内的书籍数量。
管理虚拟书库
- 编辑与删除:点击 Virtual library 按钮,通过 Edit Virtual library 与 Remove Virtual library 子菜单操作已有虚拟书库。源码中菜单由
build_virtual_library_menu动态构建(见 src/calibre/gui2/search_restriction_mixin.py),每个条目对应do_create_edit(编辑)或remove_vl_triggered(删除)。 - 默认应用:打开某个书库时希望自动应用某个虚拟书库,可在 Preferences → Interface → Behavior(偏好设置 → 界面 → 行为)中设置。
- 当前搜索作为临时虚拟书库:点击 Virtual library 按钮并选择
*current search(当前搜索) 条目,即可把当前搜索当作临时虚拟书库立即生效。源码中搜索框为空时该临时限制会被自动清除(见apply_virtual_library中对library == '*'的分支处理)。 - 标签页展示:点击 Virtual library 按钮,选择 Show Virtual libraries as tabs,可在书籍列表上方把全部虚拟书库显示为标签页,便于高频切换;标签可拖拽排序,不需要的可以关闭,关闭后可右键标签栏恢复。该功能在 GUI 层由虚拟书库标签栏(
vl_tabs)实现(参见 src/calibre/gui2/layout.py 中encoded_virtual_library与virtual_library按钮的相关代码),菜单中的 “Show/Hide Virtual library tabs” 动作则切换gprefs['show_vl_tabs']偏好。 - 快捷操作:从 src/calibre/gui2/actions/virtual_library.py 可以看到,calibre 为虚拟书库内置了两组键盘快捷键:
- Ctrl+T:快速选择(Quick select)一个虚拟书库;
- Ctrl+Alt+Shift+P:切换到上一次使用的虚拟书库(
switch_to_previous_virtual_library)。 此外,切换书库(library_changed)时会清空虚拟书库历史,避免跨书库误用。
在搜索中使用虚拟书库(vl: 前缀)
虚拟书库名称可直接作为搜索定位符使用,语法为 vl: 前缀:
vl:Read—— 找出所有位于 Read 虚拟书库中的书;vl:Read and vl:"Science Fiction"—— 找出同时位于 Read 与 Science Fiction 两个虚拟书库中的书(交集)。
规则:vl: 后面必须跟虚拟书库的名称;名称含空格时必须用双引号包裹。
对应的解析实现在 src/calibre/db/search.py 的 get_matches 中:
if location == 'vl':
vl = self.dbcache._pref('virtual_libraries', {}).get(query) if query else None
if not vl:
raise ParseException(_('No such Virtual library: {}').format(query))
try:
return candidates & self.dbcache.books_in_virtual_library(query, virtual_fields=self.virtual_fields)
except RuntimeError:
raise ParseException(_('Virtual library search is recursive: {}').format(query))
从中可以看到三个实现细节:
- 虚拟库名称通过偏好键
virtual_libraries查表解析; - 不存在的虚拟书库会抛出
ParseException(“No such Virtual library”); - 递归引用虚拟书库(如 A 引用 B、B 又引用 A)会被检测并以解析异常形式拒绝,避免死循环。
内容服务器(Content server)中的用法
vl: 搜索的一个典型应用场景是内容服务器(Content server)的访问控制。在 Preferences → Sharing over the net → Require username and password(偏好设置 → 网络共享 → 需要用户名和密码)中,可以为每个用户限制可见的 calibre 书库;对每个可见书库还可指定一条搜索表达式进一步裁剪可见书籍。使用 vl:"虚拟书库名称" 即可把可见书籍限定到某个虚拟书库内。
使用附加限制(Additional restrictions)
虚拟书库还可以叠加附加限制(Additional restrictions):它是一条你先前保存过的搜索(saved search),被应用到当前虚拟书库上,进一步收窄展示的书籍。
典型例子:假设你有一个面向 Historical Fiction(历史小说)标签的虚拟书库,又保存了一条“未读书籍”的搜索,那么点击 Virtual Library 按钮,选择 Additional restriction 选项,即可只显示“未读的历史小说”。
关于如何创建保存搜索(在搜索栏旁的 Saved Searches 框中输入名称并点击加号保存,随后可在标签浏览器的 Saved searches 下单击复用),参见 保存搜索(Saving searches)。
从源码看,“附加限制”在 src/calibre/gui2/search_restriction_mixin.py 中以独立菜单 ar_menu(Additional restriction)承载,并支持一键清除(点击书库旁的清除按钮会同时应用虚拟书库并清除附加限制,clear_vl 信号连接;按 Alt+Esc 也可清除附加限制,见 src/calibre/gui2/ui.py)。其求值即前文 books_in_virtual_library 中“虚拟书库结果 ∩ 附加限制结果”的交集运算。
小结
虚拟书库是 calibre 组织大型收藏的核心工具,它把“分区”从物理拆库升级为基于搜索表达式的逻辑视图:一条表达式定义子集,vl: 前缀让虚拟书库可参与任意组合检索,附加限制提供二次收窄,标签页模式与快捷键则让多视图切换变得流畅。无论是按作者、按评分、按阅读状态,还是配合内容服务器做用户级可见范围裁剪,虚拟书库都提供了完整而克制的解决方案。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.22 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python400
cherry-studio🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端TypeScript2 K146
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python48467
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go20843
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java34451

