第5章:Dataview 动态查询
本章结构:先理解 Dataview 的查询模型与三种用法 → 再写 DQL / DataviewJS。
前提:第4章:Templater 已完成,至少 1 本书在Books/(否则查询为空是正常的)。
预计时间:概念 15 分钟 + 实操 40 分钟
复制提示:文中示例代码块语言标为dql/js(便于网站发布)。在 Obsidian 里粘贴后,请把dql改回dataview、js改回dataviewjs。
1. Dataview 是什么
Dataview 是 Obsidian 社区插件,把 vault 里的 Markdown 笔记当作数据库来查询:
- 每一篇笔记 = 一行
- frontmatter(YAML 顶部的
---块)= 列(如title、ISBN、tags) - 你在笔记里写的 查询块 = 动态视图(列表、表格、任务、统计)
换个更直觉的理解方式:想象你在 Excel 里有一张表,每一行是一本书,列是书名、作者、评分、标签。Dataview 就是这张表的查询工具——你可以问它「显示所有待读的书」「按评分从高到低排」「只显示文学类且评分 ≥ 8 的」。不同之处在于,这张表的每一行都是一篇独立的 Markdown 文件。
它不会改笔记,只读取已有 frontmatter。
所以 Templater 负责写统一字段,Dataview 负责展示「待读有哪些」「评分 ≥8 的书」。
2. 核心功能一览
| 功能 | 说明 |
|---|---|
| DQL | Dataview Query Language,类 SQL;Obsidian 里代码块语言用 dataview(本站示例用 dql) |
| DataviewJS | Obsidian 里代码块语言用 dataviewjs(本站示例用 js) |
| 行内查询 | 段落内用反引号包裹「= 表达式」(详见 3.7 节) |
| LIST / TABLE / TASK | 三种常见输出 |
| FROM / WHERE / SORT | 筛选文件夹、条件、排序 |
| 自动刷新 | 改 frontmatter 后视图更新(有时需 Force refresh) |
3. 三种用法对比
| 用法 | 适合 | 难度 |
|---|---|---|
| DQL LIST/TABLE | 书单、待读、简单筛选 | ⭐ 本教程重点 |
| DataviewJS | 标签统计、复杂逻辑 | ⭐⭐ 需开 JS |
| 行内 | 显示「书库共 N 本」 | ⭐ 单行 |
设置里需开启:Enable Dataview;用 JS 时再开 Enable JavaScript Queries。
4. 在本系列中的角色
flowchart LR TP[Templater 写入 YAML] --> B[Books/*.md] B --> DV[Dataview 查询块] DV --> L[LIST 待读] DV --> T[TABLE 已读]
- Navigator:打开某一本书的文件
- Dataview:回答哪些书符合条件
字段名必须与 Books.md 模板一致(ISBN、tags、rating…)。
5. 跟着做:启用 Dataview
设置 → Dataview- 确认 Enable Dataview 已开
- 若本章要用 DataviewJS(3.5 节):开启 Enable JavaScript Queries
- 在本章阅读模式下直接编辑练习区即可
3.3 前置:Books 的 YAML 约定
与 Tools/Templater/Books.md 对齐,Dataview 依赖这些字段:
| 字段 | 类型 | 示例 |
|---|---|---|
title |
文本 | 白色绵羊里的黑色绵羊 |
author |
文本 | 作者名 |
ISBN |
文本 | 9787532184439 |
rating |
数字 | 7.6(豆瓣评分) |
myRating |
数字或空 | 你的评分 |
tags |
列表 | [文学] 或含 待读 |
addDate |
日期 | 2026-06-28 |
跟着做:打开 Books/白色绵羊里的黑色绵羊.md,对照上表检查字段是否存在。
3.4 跟着做:待读书单(DQL LIST)
在本章笔记或任意 MOC 中粘贴:
## 待读
```dql
LIST
FROM "Books"
WHERE contains(tags, "待读")
SORT addDate DESC
```
切换到阅读模式(或 Live Preview 中渲染 Dataview)。
验证
- 列表显示所有
tags含待读的书 - 打开一本书,把
tags里的待读改成文学(且不含待读)→ 列表少一项
语法说明
| 子句 | 含义 |
|---|---|
FROM "Books" |
只查 Books/ 文件夹 |
WHERE contains(tags, "待读") |
标签列表包含「待读」 |
SORT addDate DESC |
按入库日期倒序 |
关于数据类型的一个提醒:Dataview 会根据 frontmatter 的值推断类型。比如 rating: 7.6 被识别为数字,你可以用 rating >= 8 来筛选;addDate: 2026-06-28 被识别为日期,所以 SORT addDate DESC 按时间排序是生效的。但如果你的 frontmatter 里某个字段有时是数字有时是字符串(比如 rating: "7.6" 带引号),Dataview 可能无法正确比较——这是写 frontmatter 时需要注意保持一致性的原因。
3.5 跟着做:已读书籍表格(DQL TABLE)
## 已读(非待读)
```dql
TABLE author AS "作者", rating AS "豆瓣", myRating AS "我的", addDate AS "入库"
FROM "Books"
WHERE !contains(tags, "待读")
SORT rating DESC
```
验证:表格有表头;rating 高的排在前面。
扩展:只显示评分 ≥ 8 的书:
TABLE author, rating
FROM "Books"
WHERE rating >= 8
SORT rating DESC
3.6 跟着做:按标签统计(DataviewJS)
当 DQL 不够灵活时,用 DataviewJS(需开启 JavaScript Queries):
## 各标签书本数(不含「待读」)
```js
const pages = dv.pages('"Books"');
const tagCounts = {};
for (const p of pages) {
const tags = p.tags ?? [];
for (const t of tags) {
if (t === "待读") continue;
tagCounts[t] = (tagCounts[t] || 0) + 1;
}
}
const rows = Object.entries(tagCounts)
.sort((a, b) => b[1] - a[1])
.map(([tag, n]) => [tag, n]);
dv.table(["标签", "本数"], rows);
```
验证:输出两列表格,例如 文学 | 3。
代码逻辑
dv.pages('"Books"')— 取文件夹下所有页- 遍历每页的
tags数组 - 跳过
待读,累加计数 dv.table渲染
3.7 跟着做:行内查询(Inline)
在普通段落里写动态数字,无需单独代码块:
书架共有 [美元等号] dv.pages('"Books"').length 本书。
(Obsidian 里用反引号包裹「美元 + 等号」前缀即可渲染。)
验证:阅读模式下显示实际数量,例如在 Books/ 有 4 本则显示 4。
再试一条:待读数量
待读 [美元等号] dv.pages('"Books"').where(p => p.tags && p.tags.includes("待读")).length 本。
3.8 跟着做:带封面列的 TABLE(可选)
若 frontmatter 有 cover 且文件存在:
```dql
TABLE author AS "作者", rating AS "评分", cover AS "封面"
FROM "Books"
WHERE contains(tags, "待读")
SORT addDate DESC
LIMIT 10
```
封面列可能显示为路径文本;在 Obsidian 主题下部分版本可渲染缩略图。以你当前 Dataview 版本为准。
3.9 与 Templater 的衔接
| 阶段 | 负责插件 |
|---|---|
导入时写入 tags、ISBN、rating |
Templater + Douban |
| 阅读时自动列出「待读」 | Dataview |
改 tags 从待读 → 文学 |
你手动或 Claudian 批量改 |
| 列表自动更新 | Dataview 无需改查询 |
字段改名时:先改 Books.md 模板 → 再批量改旧笔记 → 最后改 Dataview 查询里的字段名。
3.10 性能与维护
- 笔记量在数百篇以内,Dataview 通常无感
- 若查询变慢:缩小
FROM范围;避免全库FROM "" - 改完大量 frontmatter 后:命令面板搜索
Dataview: Force refresh all views
3.11 本章练习
在本章末尾完成:
3.12 常见坑
| 现象 | 原因 | 处理 |
|---|---|---|
| 查询块显示代码不渲染 | 没开 Dataview;或编辑模式没切到 Live Preview/阅读模式 | 检查插件是否启用;尝试切到阅读模式 |
| 结果为空 | FROM 路径写错了;或者字段名和 frontmatter 不一致 |
先用 FROM "Books";确认 YAML 字段名跟查询里写的一模一样(大小写敏感) |
contains(tags, "待读") 查不到 |
tags 被写成了字符串而不是列表 | 检查 YAML:tags: 文学 不对,应该是 tags:\n - 文学(带短横线的列表格式) |
| DataviewJS 报错 | 没开 JavaScript 执行权限 | 去设置里打开 Enable JavaScript Queries |
更多片段见 附录 §B。
| ← 上一章 | 蒸馏术 主页 | 下一章 → |
|---|---|---|
| 第4章:Templater | 第6章:Navigator |