- 前端
- 知识管理
- 数据分析
【免费下载链接】obsidian-dataview
A data index and query language over Markdown files, for https://obsidian.md/.
在 Obsidian 中使用 Dataview 管理任务时,annotated隐式字段可以快速筛选出「带元数据注释的任务」,而group by子句则能把任务按任意字段分组呈现。本文以仓库内 test-vault 中的 Annotated Tasks.md 为骨架,结合官方文档与源码实现,讲解如何用task where annotated与task group by p两类查询驾驭任务元数据。
一、关联文档是什么:一个可运行的查询示例库
Annotated Tasks.md 是仓库test-vault/tasks/目录下的一个真实可运行的示例笔记,文件内容本身只有两段 Dataview 查询:
task where annotated以及分组版本:
task where p group by p它演示了 Dataview 任务查询的两个核心能力:
- 利用
annotated隐式字段过滤:只列出「文本中包含元数据字段」的任务; - 利用
group by对任务分组:按某个字段(示例中的p)把任务归组展示。
围绕这两段查询,官方文档 Metadata on Tasks and Lists 提供了完整的字段语义说明,源码则给出了底层实现依据。以下逐层展开。
二、annotated是什么:任务级元数据的布尔标志
官方定义
根据文档 Implicit Fields 中的字段表,annotated的定义是:
| 字段名 | 数据类型 | 说明 |
|---|---|---|
annotated | Boolean | 任务文本中包含任何元数据字段时为true,否则为false。 |
也就是说,一个任务只要在文本里出现了任意一处内联字段(inline field),它的annotated值即为true;完全没有任何字段注释的普通任务则为false。
源码级验证
在 src/data-model/markdown.ts 的ListItem.serialize方法中,annotated的实现就是一行判断:
annotated: this.fields.size > 0,即:该列表项(任务或普通列表项)解析出的fields 集合(Map)大小大于 0时,annotated为真。这里的fields来自任务行内所有内联字段的解析结果(见this.fields = this.fields || new Map(),位于 src/data-model/markdown.ts)。对应的序列化接口定义在 src/data-model/serialized/markdown.ts:
annotated?: boolean;由此可以确认:annotated与任务是否勾选完成无关,只与是否存在字段注释有关。一个未勾选[ ]但带有[due:: 2021-08-29]注释的任务,annotated同样为true。
三、如何让任务变成annotated:内联字段与 Field Shorthands
任务级别的元数据使用与页面相同的内联字段语法(参见 add-metadata.md)。在任务行内书写[key:: value]即可绑定字段到该任务:
- [ ] Hello, this is some [metadata:: value]! - [X] I finished this on [completion:: 2021-08-15].上面两个任务都包含字段,因此annotated均为true。
Emoji 简写(Field Shorthands)
除了标准内联字段,Dataview 还支持 Tasks 插件风格的 Emoji 日期简写。其特点是省略内联字段的方括号语法(无需写[🗓️:: 2021-08-29]),并映射为文本型字段名:
| 字段名 | 简写语法 |
|---|---|
due | 🗓️YYYY-MM-DD |
completion | ✅YYYY-MM-DD |
created | ➕YYYY-MM-DD |
start | 🛫YYYY-MM-DD |
scheduled | ⏳YYYY-MM-DD |
示例:
- [ ] Due this Saturday 🗓️2021-08-29 - [x] Completed last Saturday ✅2021-08-22 - [ ] I made this on ➕1990-06-14 - [ ] Task I can start this weekend 🛫2021-08-29 - [x] Task I finished ahead of schedule ⏳2021-08-29 ✅2021-08-22需要说明的是,当前版本仅支持上述日期类简写;优先级与重复(recurrence)简写不受支持。由于 Emoji 简写在数据层面也会产生字段,这类任务同样属于annotated = true——因此task where annotated能同时捕获「内联字段注释」与「Emoji 日期简写」两类任务。
四、task where annotated查询详解
基本用法
回到关联文档的第一段查询:
task where annotated在 TASK 查询中,任务本身就是顶层数据,因此隐式字段可以不带前缀直接使用(参见文档 Accessing Implicit Fields in Queries)。该查询返回所有「包含任意元数据字段」的任务。
若在非 TASK 查询中访问任务字段,则需要通过file.lists/file.tasks间接访问,并借助列表函数(如any)逐项判断:
LIST WHERE any(file.tasks, (t) => t.annotated)该写法会返回所有「含有带注释任务」的笔记链接。
结合其它任务隐式字段的组合筛选
annotated常与下列任务隐式字段组合使用,形成更精细的筛选条件:
| 字段名 | 类型 | 含义 |
|---|---|---|
status | Text | [ ]括号内的状态字符,一般为空格(未完成)或x(完成),也支持自定义状态插件 |
checked | Boolean | 状态字符非空(即括号内不是空格),不一定等于x |
completed | Boolean | 本任务是否被标记为x完成,不考虑子任务;自定义状态(如[-])时checked为真而completed为假 |
fullyCompleted | Boolean | 本任务及其所有子任务是否全部完成 |
text | Text | 任务纯文本,含字段注释 |
line/lineCount | Number | 任务所在行号 / 占用的 Markdown 行数 |
path | Text | 任务所在文件的完整路径,等价于页面的file.path |
section | Link | 任务所在章节的链接 |
tags | List | 任务文本中的标签 |
outlinks | List | 任务中定义的链接 |
link | Link | 任务附近最近可链接块的链接 |
children | List | 任务的子任务 / 子列表 |
task | Boolean | 是否为任务(否则是普通列表项) |
annotated | Boolean | 是否含元数据字段 |
parent | Number | 父级任务的所在行号(无则为null) |
blockId | Text | 使用^blockId定义的块 ID(无则为null) |
例如,筛选「带注释且未完成」的任务:
task where annotated and !completed任务属性继承:页面字段向上流动
一个容易被忽略的事实是:任务会继承其所在页面的全部字段(文档 Implicit Fields 中的 info 提示)。因此若页面有rating字段,在 TASK 查询中同样可以在任务上访问它。不过要注意,annotated判断的是任务自身文本中的字段(this.fields.size > 0),页面级字段不会让任务的annotated变为true。
五、group by分组查询详解
关联文档中的第二段查询
task where p group by p在 test-vault 中,p是示例笔记里自定义的字段名(占位符),真实使用时替换为你的实际字段即可,例如按due分组:
task where due group by due分组查询的语义
group by是 Dataview 查询的顶层子句(与where、sort等并列),其效果是把结果按指定字段的值聚合为组。查询类型由首行关键字决定——TASK、TABLE、LIST、CALENDAR四选一(参见 src/query/parse.ts 对TABLE|LIST|TASK|CALENDAR的解析,以及 src/query/query.ts 中的QueryType定义)。task关键字不区分大小写,因此关联文档中用小写task书写同样有效。
分组后每组通常呈现为「组值 + 组内任务」的层级结构,适合按日期、状态、负责人等维度组织任务视图。参考同目录下的 Grouped Sorted Tasks.md,还可以在分组前先排序,保证组内顺序稳定:
task where p sort p asc group by p与排序、筛选的组合
test-vault 中 Sorted Tasks.md(实际文件为 Sorted Tasks.md)展示了不含分组的排序写法,可作为对照:
task where p sort p asc将annotated过滤与group by结合,即可得到「只统计带元数据注释的任务,并按字段分组」的查询:
task where annotated and due sort due asc group by due六、annotated字段的典型使用场景
- 审计未标注任务:列出所有不含任何元数据字段的任务,检查是否有遗漏的日期、负责人等注释:
task where !annotated - 统计带注释任务:配合
GROUP BY或聚合函数(如length)统计库中带元数据任务的数量与分布。 - 联动 Emoji 简写:由于简写会映射为字段,
task where annotated也能覆盖「使用 Tasks 风格 Emoji 日期」的笔记,实现两种注释风格的统一检索。
七、从源码理解:任务字段的生命周期
结合 src/data-import/markdown-file.ts 的解析逻辑(completed: rawElement.task == "X" || rawElement.task == "x")与 src/data-import/inline-field.ts 对completed/due/done等特殊 Emoji 字段的解析,可以看到完整链路:
- Markdown 文件被解析为列表项
ListItem,任务状态字符写入task.completed等属性,行内字段写入fieldsMap; serialize时根据this.fields.size > 0生成annotated布尔值(src/data-model/markdown.ts);- 查询引擎按
where/group by子句对序列化后的任务对象求值并渲染。
因此annotated的判定完全取决于解析阶段字段收集的完备性:只要任务行存在任意内联字段或 Emoji 日期简写,fields.size即大于 0。这也解释了为何annotated与勾选状态(completed)相互独立——它们是两个维度上的布尔标志。
八、小结
annotated是任务级隐式布尔字段,语义为「任务文本是否含元数据字段」,源码实现为this.fields.size > 0(src/data-model/markdown.ts),可与completed、checked、due等字段自由组合筛选。group by可按任意字段对 TASK 查询结果分组,与where、sort组合后可以构建「带注释任务」的维度化视图。- 关联文档 Annotated Tasks.md 是一个可直接放入自己 Vault 运行的示例;完整的任务字段语义可查阅 metadata-tasks.md,内联字段语法见 add-metadata.md,查询结构说明见 query-types.md 与 structure.md。
将task where annotated与group by结合使用,你可以轻松从任意规模的 Markdown 任务库中,提炼出「已标注元数据的任务」并按维度聚合,让任务管理真正数据化。
- 前端
- 知识管理
- 数据分析
【免费下载链接】obsidian-dataview
A data index and query language over Markdown files, for https://obsidian.md/.
相关推荐
Obsidian Dataview 查询语言实战示例详解:从 DQL 语法到源码级原理
Obsidian Dataview 查询语言实战示例详解:从 DQL 语法到源码级原理 本文围绕 Dataview 官方示例文档中的 5 个经典 DQL(Dat
前端知识管理数据分析Obsidian Dataview查询示例大全:100+实用查询代码片段
Obsidian Dataview查询示例大全:100+实用查询代码片段 一、基础查询入门 1.1 核心查询类型概览 Obsidian Dataview提供四种
前端知识管理数据分析Wagtail 3.0.1 版本全解析:WAGTAILADMIN_BASE_URL 新警告与 8 项关键修复
Wagtail 3.0.1 版本全解析:WAGTAILADMIN_BASE_URL 新警告与 8 项关键修复 本文基于仓库内 docs/releases/3.0
前端知识管理数据分析
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考