Obsidian Dataview 查询指南
用 Dataview 从 Obsidian frontmatter、文件元数据、链接与任务中动态查询列表和表格;重点是数据模型、DQL、调试与性能边界,而不是把插件当作第二套数据库。
[!info] related notes
- 所属 MOC: Obsidian MOC
- 学习追踪: Obsidian 学习追踪系统
- 元数据规范: [[knowledge-base-metadata-reference|知识笔记元数据规范]]
- 相邻工具: Database Folder 插件指南
- 文件元数据解析: gray-matter
Obsidian Dataview 查询指南
目标
完成后应能:
- 明确 Dataview 在查询什么;
- 用 DQL 按 folder、tag、frontmatter、link、date 过滤笔记;
- 用 TABLE / LIST / TASK 输出结果;
- 排查“为什么查不到”;
- 知道何时应该用 Bases,而不是继续堆复杂 Dataview。
心智模型
Dataview 不把 Markdown 变成真正数据库。
更准确的模型是:
Markdown / frontmatter / links / tasks
↓
Dataview index
↓
DQL / DataviewJS query
↓
Dynamic projection
Source of Truth 仍然是 Markdown 与 frontmatter。
查询结果只是 projection,不应该手工复制回第二份列表。
数据来源
Frontmatter
例如:
---
title: CORS
tags: [type/concept, tech/dev/frontend]
mastery: 3
updated: 2026-09-30T00:00:00+08:00
---
Dataview 可以直接查询:
titletagsmasteryupdated
File Metadata
常见:
file.namefile.pathfile.folderfile.ctimefile.mtimefile.tagsfile.inlinksfile.outlinks
Tasks
Markdown task:
- [ ] Review CORS
- [x] Read Same-Origin
可通过 TASK query 汇总。
最小 DQL 结构
常见结构:
TABLE mastery, description
FROM "z"
WHERE mastery
SORT mastery ASC
LIMIT 20
可以理解成:
Output
→ Scope
→ Filter
→ Transform/Group
→ Sort
→ Limit
TABLE
适合比较多个字段:
TABLE mastery, status, description
FROM "z"
WHERE contains(tags, "resource/react")
SORT mastery ASC
如果字段不存在,先检查 frontmatter,而不是先怀疑 Dataview。
LIST
适合只需要导航:
LIST
FROM #tech/security
SORT file.name ASC
如果只是“展示一组链接”,LIST 往往比 TABLE 更轻。
TASK
例如聚合某目录未完成任务:
TASK
FROM "projects"
WHERE !completed
TASK query 是任务 projection,不替代真正任务管理系统的状态机。
WHERE
数值
TABLE mastery
FROM "z"
WHERE mastery <= 2
字符串
TABLE description
FROM "z"
WHERE status = "growing"
前提是你的 schema 真的存在 status 字段。
Thought Forest 的状态目前主要来自 status/* tag,因此不要机械照搬不存在的字段。
Tag
LIST
FROM #tech/ai
或:
TABLE file.tags
FROM "z"
WHERE contains(file.tags, "#tech/ai")
具体表现取决于 Dataview 对 tag 的标准化形式,查询不匹配时先打印实际值。
Link
例如找链接到某笔记的页面:
LIST
FROM "z"
WHERE contains(file.outlinks, [[cors]])
对于知识图谱问题,优先确认你要的是:
- outgoing link;
- backlink;
- tag;
- folder;
不要用 folder 模拟语义关系。
SORT
TABLE mastery, updated
FROM "z"
WHERE mastery
SORT mastery ASC, updated ASC
排序只是展示优先级,不改变数据本身。
GROUP BY
例如按 mastery 分组:
TABLE length(rows) AS Count
FROM "z"
WHERE mastery
GROUP BY mastery
SORT mastery ASC
但注意:
mastery 是序数能力等级,不应该拿平均数伪装成精确百分比。
详见 学习中的掌握。
学习 Dashboard 示例
当前重点
TABLE mastery, description
FROM "z"
WHERE mastery AND mastery <= 2
SORT mastery ASC
等待迁移测试
TABLE mastery, description
FROM "z"
WHERE mastery = 3
SORT file.mtime ASC
它们的价值是驱动下一步学习,而不是做漂亮统计。
最近修改
TABLE file.mtime
FROM "z"
SORT file.mtime DESC
LIMIT 20
适合排查最近变化,但 mtime 不是知识成熟度。
DataviewJS 什么时候用
只有 DQL 表达不了时再考虑 DataviewJS。
例如需要:
- 自定义复杂转换;
- 程序化渲染;
- 多阶段数据加工。
不要因为“JS 更自由”就默认用 JS。
复杂脚本意味着:
- 更难阅读;
- 更难迁移;
- 更容易和插件 API 版本耦合。
调试顺序
查询为空时:
1. FROM 范围对吗?
2. 实际字段名是什么?
3. 字段的真实类型是什么?
4. tag 是否带 # / 是否嵌套?
5. path/folder 大小写是否匹配?
6. link 比较的是 Link object 还是 string?
7. 条件逐个加回去
最有效的方法是先把查询缩到:
TABLE file.path
FROM "z"
LIMIT 10
确认 scope,再逐步加 WHERE。
性能边界
Vault 越大,越应该:
- 限定 folder/tag;
- 避免每个页面执行全库复杂查询;
- 减少重复 DataviewJS;
- 对 Dashboard 使用有限的结果集;
- 不把一篇笔记塞几十个动态查询。
优化目标不是“查询语法最短”,而是减少不必要扫描和复杂转换。
Dataview 与 Bases
如果需求只是:
- MOC 中展示链接;
- 读取 frontmatter;
- 表格筛选与排序;
- 直接编辑属性;
优先考虑 Obsidian Bases。
Dataview 更适合:
- 灵活 DQL;
- 聚合;
- 动态计算;
- TASK query;
- 复杂 query projection。
选择原则:
简单结构化视图
→ Bases
复杂动态查询
→ Dataview
元数据纪律
不要为了一个 Dashboard 随意发明新字段。
先查:
[[knowledge-base-metadata-reference|知识笔记元数据规范]]
例如 Thought Forest 已经规定 mastery,就不要再创建:
rating: 4
knowledge_score: 80
mastery_percent: 80
来表达同一事实。
常见失败模式
手工维护查询结果
动态结果又被复制成静态列表,形成第二份真相。
为了查询改变知识结构
先为了 Dataview 好查而乱造 folder/tag/schema。
正确方向应是:
知识模型
→ metadata schema
→ query
而不是反过来。
用统计代替学习
“今天查询出了 300 篇笔记”不是学习证据。
把 Dataview 当写数据库 API
它的核心价值是 query/projection,不是 transaction system。
无提示执行检查
不看正文:
- 创建三个带不同 mastery 的测试笔记;
- 用 TABLE 查询 mastery <= 2;
- 用 LIST 查询某 tag;
- 用 link 查询某个目标节点的出链/入链场景;
- 制造一个字段类型错误并定位;
- 把一个全库慢查询改成范围更小的查询;
- 判断一个 MOC 表格应该用 Bases 还是 Dataview,并解释理由。