你读得懂的 Dataview 教程
前言
尽可能用普通用户能听得懂的方式讲述 Obsidian 神级插件 Dataview 的使用方法。仅入门。
Dataview 是什么
就是查询,直白点,搜索——从笔记中搜索,并将结果呈现出来。
它有两种查询语言,一种是 DQL,就是 Dataview 自己的查询语言,这个比较简单。书写时把代码放进 dataview
代码块中。另一种是 JavaScript,这种对于有 JS 基础的人来说更加简单,因为可以无需学习而直接上手,书写时把代码放进 dataviewjs
代码块中。另外还有行内代码模式,但都是基于这两种语言的。
为什么封神
之所以封神,因为可以运行 JS,也就可以做到几乎所有 JS 可以做到的事情。这时候简直没有了局限性,也就不再止步于搜索这一个功能。所以,想要真正发挥 Dataview 的潜力,学习 JS 是最佳捷径。确实这条路投入成本很高,但是这项技能可以应用的场景也不仅仅限于这一个插件,总体上投入与回报是对等的。
搜索做了什么
三件事情:
- 从哪里找(来源)
- 查找什么(过滤)
- 如何呈现(呈现)
比如在所有笔记里查找今天创建的笔记,然后以列表形式呈现。
DQL 的公式
- 呈现形式(呈现)
- 内容来源(来源)
- 结果过滤(过滤)
请和上面做一下对应,然后我们开始逐条分析:
呈现形式
有四种:
LIST
列表形式TABLE
表格形式TASK
任务列表形式CALENDAR
日历形式
Dataview 的查询首先要说明以何种形式呈现,并且必须说明。而来源可以省略(默认所有笔记),过滤可以省略(即不做任何过滤)。可尝试如下代码(笔记数量大时慎用,可在末尾加入一行 LIMIT 10
限制结果数量):
```dataview
LIST
```
其他几种形式也可以自行尝试。
内容来源
如上方,以列表形式呈现,那么要呈现哪些笔记呢?这时要使用 FROM
语句,这里不做过多解读,直接举例,大家按需套用即可:
所有具有特定标签的笔记
```dataview
LIST
FROM #TheTag
```
所有某文件夹下的笔记
```dataview
LIST
FROM "日记/2024"
```
特定的某个文件
```dataview
LIST
FROM "日记/2024/12/31.md"
```
这个和上面非常像,如果有同名文件和文件夹,会优先选择文件夹,所以想指定文件时,建议带上后缀。
所有特定文件的出链或者入链
所有链接到 OneNote.md
的笔记。
```dataview
LIST
FROM [[OneNote.md]]
```
OneNote.md
内链接到的所有笔记。
```dataview
LIST
FROM outgoing([[OneNote.md]])
```
当前文件
```dataview
LIST
FROM [[#]]
```
或者
```dataview
LIST
FROM [[]]
```
组合来源
在这个文件夹里同时具有后面标签的所有笔记。即需要同时满足所有条件
```dataview
LIST
FROM "日记/2024" and #Goodday
```
在这个文件夹里,或者(不一定在这个文件夹里,但)具有这个标签的笔记。即满足其中一个条件即可。
```dataview
LIST
FROM "日记/2024" or #Goodday
```
反向条件
-
表示逆转该条件,下方表示所有不具有此标签的笔记
```dataview
LIST
FROM -#TheTag
```
遗漏内容
上面有些例子中明确的就是一个文件,这似乎没什么列出的必要性。这是因为为了让格式完整同时易于理解,所以都使用了最简单的 LIST
呈现,实际可以列出的不只是文件,还有列表、任务等,这时候即便源是一个文件,但还是可能有多条结果可以列出。例如:将 LIST
换成 TASK
就是列出文件中所有任务了
结果过滤
用 WHERE
语句,WHERE
后面是一个表达式,通过判断表达式是否成立,决定是否保留这条结果。
```dataview
TASK
FROM #TodoList
WHERE !completed
```
上面表示所有未完成的任务。!
为否定,否定了 completed
这一属性,即任务已完成,则视为不成立(忽略),任务未完成,则视为成立(保留)。
WHERE
语句可以多次数用,进行反复过滤。
增加细节
上面最基础的公式你已经了解。我们来提升复杂度。
呈现样式
LIST
后面可以再带一个值,比如LIST file.folder
就带上了文件夹。这个值可以是通过计算得出的,这样就可以通过拼接呈现多个值。如:LIST "文件路径: " + file.folder + " _(创建于: " + file.cday + ")_"
TABLE
可以自定义列:TABLE started, file.folder, file.etags
,这里的started
是在 frontmatter 中自定义的属性,file.
开头的是 Dataview 给文件添加的元数据。并且可以自定义列的名称:TABLE started, file.folder AS 路径, file.etags AS 标签
CALENDAR
可以添加一个时间相关的字段来说明根据哪个时间决定在日历上的标记,比如:CALENDAR file.ctime
就是根据文件的创建时间。LIST
和TABLE
都可以不带 ID,就是去掉默认的文件链接部分信息:TABLE WITHOUT ID
排序
用 SORT
语句决定结果如何排序
分组
用 GROUP BY
根据条件决定如何对结果分组呈现
数量限制
用 LIMIT
限制最终结果数量,这个建议先做排序,这样可以保证保留下来的结果更符合你的需求,比如截止时间最靠近的五个任务之类。
扁平化
这个有点抽象,用 FLATTEN
语句将一些结构复杂的内容压扁,使得可以用表格、列表等形式呈现。
不够详细?!
后面几个没听懂?去读以一下文档吧,不在这里举例了,最简单的用法下按着示例套公式也完全没问题。但是分组、排序后面可以接表达式,这时候复杂度就比较高了。这就意味着非常灵活,而灵活的前提是对基础知识的足够了解,所以这里我不做示例和展开,否则我写出来没问题,但是想照猫画虎却非常难(基础知识的缺失),这时候就要熟读文档了。
但这时候我有一个疑惑:同样是花功夫学习,为什么不去学在很多地方都可以使用的 JS,而去学习没什么通用性的插件的私有语言呢?所以在 DQL 上过多的投入并不差很明智的选择。