Dataview 专题:用查询语言唤醒沉睡的笔记
从元数据到 DQL 语法,再到 DataviewJS,系统掌握 Obsidian 最强大的数据查询引擎。
如果说 Obsidian 是一座堆满笔记的图书馆,那 Dataview 就是那位记得每本书位置和标签的图书管理员。它为 Markdown 文件建立了一个高性能索引,让你用一种类似 SQL 的查询语言(DQL),从全仓库的笔记里实时检索、过滤、排序、分组。本篇带你从元数据起步,一路走到 DQL 全语法与 DataviewJS 门口。
Dataview 是什么
Dataview(作者 blacksmithgu)是一个”查询引擎”而非”编辑器”——它只读取、不改写你的笔记。它会在后台扫描整个仓库,把笔记的属性、列表、任务都建成索引,然后在 ```sql 代码块里渲染出动态视图。视图随笔记内容变化自动更新,无需手动维护。
元数据从哪里来
Dataview 能查询的前提,是笔记里有”字段(field)“——即一对键值。字段有三个来源:
1. Frontmatter(YAML 属性):写在笔记最顶部 --- 之间的内容,会自动成为字段。这是最规范的来源。
---
title: 项目凤凰
status: 进行中
due: 2026-08-15
priority: 5
tags:
- project
---
这里 status、due、priority 都成了可查询字段。注意 YAML 里一个冒号即可。
2. 行内字段(Inline Fields):用 键:: 值 的双冒号语法,写在正文任意位置。
本周进度:: 70%
[心情:: 满意] 今天的效率不错。
独占一行的字段用 键:: 值;嵌在句子里或写在任务/列表项上的,要用方括号包起来 [键:: 值]。注意是双冒号,这是与 frontmatter 最关键的区别。
3. 隐式字段:Dataview 自动索引的内容,无需你手动添加。每篇笔记都自带一组 file.* 字段,比如 file.name(文件名)、file.ctime(创建时间)、file.mtime(修改时间)、file.tags(标签)、file.lists(列表项)、file.tasks(任务)、file.day(从文件名或属性推断的日期)等。
DQL 查询结构
每条 DQL 查询都遵循同一骨架:一个查询类型开头,可选一个 FROM 指定来源,再跟任意数量的数据命令。只有查询类型是必填的。
```sql
<查询类型> <字段>
FROM <来源>
<数据命令> <表达式>
<数据命令> <表达式>
### FROM——圈定范围
`FROM` 接受标签、文件夹或链接作为来源,可用 `AND`/`OR`/`NOT` 组合:
```sql
LIST
FROM "项目/凤凰" -- 某文件夹及其子文件夹
FROM #project -- 带某标签的笔记
FROM #status/open OR #status/wip
FROM (#project AND "30 工作") OR outgoing([[看板]])
FROM 只能出现一次,且必须紧跟查询类型之后。
四种查询类型
- LIST:项目符号列表,可附带一个字段。
- TABLE:表格,每行一篇笔记,可指定多列字段。
- TASK:交互式任务清单,可直接勾选。
- CALENDAR:月历视图,按日期打点。
TABLE status, due, priority
FROM #project
WHERE status = "进行中"
SORT priority DESC
数据命令五件套
WHERE 过滤、Sort 排序、GROUP BY 分组、LIMIT 限量、FLATTEN 展开。除 FROM 外,它们可多次出现、按书写顺序执行。
-
WHERE:按字段筛选。
LIST WHERE due AND due < date(today) -
SORT:按字段升降序,
ASC/DESC。LIST FROM #project SORT file.ctime DESC LIMIT 10 -
GROUP BY:按字段打包,分组后原始行变成
rows数组。TASK WHERE !completed GROUP BY file.link SORT rows.file.ctime ASC -
LIMIT:只保留前 N 条结果。
-
FLATTEN:把一个多值字段”拆”成多行,常用于展开列表项。
TABLE L.text AS "要点" FROM "日记" FLATTEN file.lists AS L WHERE contains(L.text, "想法")
常用函数
Dataview 内置了大量函数,可在 WHERE、SORT、TABLE 列等任何表达式里使用。挑最常用的几类:
构造与转换
date(any):把字符串或链接解析为日期对象,如date("2026-08-15")。dur(any):解析时长,如dur("8 hours")。number(string)、string(any)、typeof(any):类型转换与判断。link(path, [display]):构造一个内链对象。
字符串
contains(object|list|string, value):判断是否包含某值,最常用。split(string, delimiter, [limit]):按分隔符切分字符串。regexmatch(pattern, string):正则匹配,返回布尔值。regexreplace(string, pattern, replacement):正则替换。lower(s)、upper(s)、replace(s, old, new)、startswith(s, prefix)。
日期与时长
date(today)、date(now):今天、此刻。dateformat(date, string):按 Luxon token 格式化日期。dur(...)可做日期运算,如date(today) - file.ctime算出”距今多久”。
工具
default(field, value):字段为空时给默认值。choice(bool, left, right):三元表达式,choice(priority > 3, "重要", "普通")。length(array)、sort(list)、reverse(list)、unique(array)、join(array, sep)。
[!note] 函数向量化 大多数函数既能作用于单个值,也能作用于列表——传列表时,函数会对每个元素分别求值并返回新列表。比如
lower(["YES", "NO"])会得到["yes", "no"]。
实战查询示例库
未完成且已逾期的任务
TASK
WHERE !completed AND due AND due < date(today)
SORT due ASC
近 7 天创建的笔记
TABLE file.ctime AS "创建于", file.tags AS "标签"
WHERE file.ctime >= date(today) - dur(7 days)
SORT file.ctime DESC
按状态分组的项目
TABLE rows.file.link AS "项目"
FROM #project
GROUP BY status
SORT status ASC
读书笔记评分榜
TABLE rating AS "评分", author AS "作者"
FROM "书籍"
WHERE rating
SORT rating DESC
LIMIT 10
把每条列表项展开成一行
TABLE L.text AS "金句"
FROM #摘抄
FLATTEN file.lists AS L
WHERE contains(L.text, "努力")
DataviewJS:更自由的进阶玩法
当 DQL 不够用时,可以用 ```javascript 代码块写 JavaScript。它把 Dataview 的索引数据通过 dv 对象暴露给你,能实现 DQL 做不到的复杂逻辑:
```javascript
dv.table(
["笔记", "字数"],
dv.pages("#project")
.map(p => [p.file.link, p.file.size])
.sort((a, b) => b[1] - a[1])
.slice(0, 10)
)
常用 API:`dv.pages(source)` 取页面、`dv.table(headers, data)` 画表、`dv.list(values)` 画列表、`dv.taskList(pages)` 画任务、`dv.markdownTable()` 输出纯 Markdown。
> [!warning] DataviewJS 的安全边界
> DataviewJS 本质是在你的仓库里执行任意 JavaScript,能力等同于一个插件。因此它默认是关闭的,需在 Dataview 设置里手动开启"Enable JavaScript Queries"。只运行你看得懂或来自可信来源的脚本,不要随意复制网上的 dataviewjs 代码就跑。
## Dataview vs Bases
Obsidian 1.9 引入的核心插件 Bases,和 Dataview 解决的是同一类问题——把笔记按属性组织成结构化视图。它们的取舍如下:
| 维度 | Dataview | Bases |
|---|---|---|
| 出处 | 社区插件 | 官方核心插件 |
| 查询方式 | 类 SQL 代码块,文本驱动 | 图形化视图,所见即所得 |
| 灵活度 | 极高,支持函数、JS、FLATTEN 等 | 适中,覆盖常见排序/过滤/分组 |
| 上手难度 | 需学 DQL 语法,门槛略高 | 拖拽点选,对新手友好 |
| 数据修改 | 只读,不能直接改属性 | 可在视图里直接编辑属性 |
| 移动端 | 支持,但复杂查询略卡 | 原生支持,体验统一 |
简单结论:**想要"看板式"直观管理和就地编辑,用 Bases;想要极致灵活的动态查询和复杂逻辑,用 Dataview。** 二者并不互斥,完全可以并存——日常清单交给 Bases,复杂报表交给 Dataview。
Dataview 的学习曲线确实存在,但每一分投入都会以"自动化"的形式偿还。从今天起,给你的重要笔记加上 frontmatter,再写第一条 `LIST FROM #project` 试试——你会感到笔记"活"了起来。