Day 23 : 插件篇 02 — 如何在 Obsidian 中自动汇整笔记?使用 Dataview 查询与呈现符合条件的笔记

一、介绍

这是 Obsidian 使用教学 — 插件篇的第 2 篇文章。

上一篇文章 中,我介绍了 Note Refactor 插件,可以快速帮我们拆分笔记。你可以在下方的文章复习内容:

这篇文章想介绍另一款 Obsidian 中的神器 — Dataview,一款类似 SQL 语法 (资料库的结构化查询语言, Structured Query Language) 的查询语言。

Dataview 可以快速查询特定条件的笔记,并且用 table (表格), list (清单), task (待办事项) 呈现这些笔记条目。

二、如何使用 Obsidian Dataview 插件?

1. Dataview 简介

参考 Dataview 插件文件 ,目前 Dataview 提供 2 种查询方式:预设语法 和 Dataview Javascript 语法。由於後者需要一定的技术知识,因此本篇只会介绍前者。

查询结果范例如下:

备注:若想要了解 Dataview Javascript 的应用,可参考 这篇文章

2. 在笔记中建立查询栏位

(1) 自行建立

Dataview 能够查询的栏位是由我们自己建立的,因此在使用 Dataview 之前,我们必须在每一则笔记中建立需要的资料栏位,以利未来查询。

目前建立栏位的方法有 2 种:

▶︎ 在 YAML 区加入栏位

YAML 是一种描述设定的文字格式,通常使用人性化的语言来撰写,以便让阅读者可以直接明白它要表达的意思。

在 Obsidian 中,我们可以用上下 --- 包住一段文字,这段文字就称为 YAML。而在 YAML 区中,我们会用 <栏位名称> : <值> 来格式来定义栏位的值。

例如下方的 YAML 区域包含了 date 和 aliases (笔记别名)。

如果 YAML 文字写得正确,在切换成 Preview Mode 时就会看到 Metadata 的文字。

如果写的不正确,就会出现 INVALID YAML 的文字。

在 YAML 区域定义的栏位都可以在後续被 Dataview 当作栏位搜寻到。想要了解更 YAML 格式如何写,可以参考 Obsidian 的官方文件

▶︎ 使用 inline field 加入栏位

另外一种在笔记中建立栏位的方式,称为 inline field。它是由 Dataview 开发者自行定义的格式,必须写在 YAML 区块 (即 --- 外面),并且用 <栏位名称>  <值> 的格式。

inline filed 相较於 YAML,在栏位值的定义上更有弹性。因为在 YAML 区中,合法栏位值是不能包含 [[]] 的 (虽然你硬要写 obsidian 也不会报错,但在程序世界中这样定义 YAML 栏位是不正确的观念)。

我建议如果要建立的笔记栏位值需要写 [[]] ,一律使用 inline field 的格式较好。范例如下图:

你可能会好奇说:「那我到底需要建立哪些栏位呢?」

这个答案完全依据你个人需求而定,如果你参考我的 Metadata 格式,基本上会有以下栏位:

在刚使用 Obsidian 初期,你不需要一次增加这麽多栏位,可以依照自己的笔记需求慢慢增加就好。

(2) Dataview 内建栏位

除了自行建立栏位,Dataview 也提供许多内建的栏位可以使用。参考 官方文件 如下,由於解释已经蛮浅白的我就不翻译了:

  • file.name: The file title (a string).
  • file.folder: The path of the folder this file belongs to.
  • file.path: The full file path (a string).
  • file.link: A link to the file (a link).
  • file.size: The size (in bytes) of the file (a number).
  • file.ctime: The date that the file was created (a date + time).
  • file.cday: The date that the file was created (just a date).
  • file.mtime: The date that the file was last modified (a date + time).
  • file.mday: The date that the file was last modified (just a date).
  • file.tags: An array of all tags in the note. Subtags are broken down by each level, so #Tag/1/A will be stored in the array as [#Tag, #Tag/1, #Tag/1/A].
  • file.etags: An array of all explicit tags in the note; unlike file.tags, does not include subtags.
  • file.inlinks: An array of all incoming links to this file.
  • file.outlinks: An array of all outgoing links from this file.
  • file.aliases: An array of all aliases for the note.
  • file.day: An explicit date associated with the file

这里的 file 指的是笔记档案 (.md) 的意思。

3. 基本查询格式

Dataview 的基本查询格式如下:

[TABLE|LIST|TASK] field1, field2, ..., fieldN FROM #tag or "folder" or [[link]]
WHERE somefield = somevalue
COMMAND argument

用 ```dataview 当作开头,最後用 ``` 将指令包住。

这样看可能太复杂了,我们换另一种比较好理解的格式:

输出格式(Table/List/Task) 栏位名称    
from [ #tag 或 资料夹 或 [[笔记]] ]   
where 条件   
sort 栏位 [排序]   

下面我们逐行拆解说明。

▶︎ 决定呈现样式 — Table, List, Task

Dataview 支援 3 种形式呈现查询结果:

  • Table : 表格
  • List : 清单
  • Task : 待办任务

其中 Table 和 List 是我最常使用的,Task 几乎没有用到。

下方是范例。请留意表格、清单、待办事项的呈现都是依据内建的主题样式 CSS 决定。

▶︎ 要查询哪里

决定了样式之後,接下来我们要告诉 Dataview 资料来源是什麽。目前 Dataview 支援 3 种形式的资料来源:

  • tag : 可指定 #tag 当作资料来源
  • folder : 可指定特定资料夹中的笔记
  • [[笔记]] : 可指定连结到「笔记」的其他笔记当作来源

20211008-CleanShot 2021-10-08 at 16.06.50@2x

例如指定 [[product strategy MOC]],抓出连结到 product strategy MOC 的笔记。

▶︎ 加入筛选条件

Where 的意思代表筛选资料,也就是将资料源的资料依据特定条件呈现。

我常用的筛选条件有:

1. 24 小时内修改的笔记

where file.mtime \>= date(today) - dur(1 day)

2. 笔记档案名称不包含特定文字 (如果要包含把 ! 拿掉即可)

where !contains(file.name,"不包含的文字")

如果要看更多范例,可以看 官方文件的这一页

▶︎ 决定如何排序资料

最後我们可依据个人需求调整查询结果的排列顺序,使用的是 sort 这个关键字。

你可以依据日期 (date)、档案修改时间 (file.mtime)、档案建立时间 (file.ctime)…来做排序。如果要正序就用 asc 这个关键字,倒序就用 desc 这个关键字。

例如依据档案建立日期倒序排列 (即最新到最旧),可以写成

sort file.ctime desc

三、实战案例 — 看看 Obsidian Dataview 可以用在哪里

1. 写作灵感提示

我在《如何透过写笔记帮助自己深度思考 ? 使用 HQ&A 笔记法,结合「费曼学习法」与「间隔重复」帮自己学得更好》介绍了 HQ&A 的笔记格式,其中 Question 和 Answer 非常适合当作写作灵感的提示。

例如今天我的写作主题是「产品策略」,我可以搜寻「product strategy MOC (即产品策略主题)」笔记,利用 Dataview 将所有连结到此主题的 HQ&A Note 用表格呈现出来。

▶︎ 栏位设计

我在每一则笔记中,都有加入 QuestionAnswer 两个栏位。

▶︎ Dataview 语法

table question, answerfrom [[product strategy MOC]]
where !contains(file.name,"daily note")
sort status desc, file.mtime desc

▶︎ 呈现结果

2. 每日复盘

在每一天傍晚,我会用 Dataview 查询今天有对哪些笔记做修改,当作今日个人笔记的复盘。

▶︎ Dataview 语法

list from ""WHERE file.ctime >= date(today) - dur(1 day)

▶︎呈现结果

3. 自动化汇整名词的相关文章

我在 Obsidian 中会别针对「名词」做笔记,纪录我对每一个新名词的理解,并且用 Dataview 汇整所有使用到此名词 (有连结) 的笔记。

例如 PARA 分类系统 笔记中,目前有 2 篇笔记都有使用 PARA 这个名词。这个用法特别适合拿来整理某则笔记的参考文献。

▶︎ Dataview 语法

table parent-link as "父连结", file.mtime as "更新时间", file.ctime as "建立时间", status as "笔记状态", file.inlinks as "相关连结"
from [[PARA system]]
sort status desc, file.mtime desc

▶︎ 呈现结果

4. 自动化汇整书籍笔记

阅读完一本书籍後,我会利用 Note Refactor 这款插件将书籍中的笔记全部拆分出去,并且透过 Dataview 将这本书籍的相关笔记自动汇整。

这个案例的 Dataview 语法跟「自动化汇整名词的相关文章」其实是一样的,只是是用在书籍笔记中。例如下方是《读懂一本书》的笔记整理。

▶︎ Dataview 语法

table parent-link as "父连结", file.mtime as "更新时间", file.ctime as "建立时间", status as "笔记状态", file.inlinks as "相关连结"
from [[{读懂一本书]]
where !contains(file.name, "MOC")
sort status desc, file.mtime desc

▶︎ 呈现结果

四、使用 Obsidian Dataview 的建议

Dataview 相对於其他 Obsidian 插件是比较难上手的,在踩过无数雷坑後我有以下 3 点建议。

1. 注意 Emoji Tag 的使用

如果你要像我一样使用 Emoji 当作 Tag,请注意不要使用 Obsidian Community Plugin — Emoji Toolbar 来插入。

Emoji Toolbar 插件

使用 Emoji Toolbar 插入的 Emoji 是无法被 Dataview 读取的,这点要特别注意。

2. 学会自己查询文件

目前网路上关於 Dataview 的学习资源还没有很多,加上每个人笔记栏位设计的格式都不相同,可能你遭遇的问题是别人从来没碰过的,因此未必都能获得解答。

此时官方文件会是你最好的帮手,虽然文件的详细程度还有待加强…但搜寻一遍官方文件後几乎都可以想得的查询语法。

如果不幸地你还是无法自己排除问题,以下有 2 个管道可以碰碰运气 (不保证有人回应):

  • Obsidian Forum : Obsidian 官方论坛,使用 Dataview 当作关键字查询是否有类似问题贴文
  • Obsidian Discord : Obsidian 官方 Discord 讨论频道,有非常多大神常驻,可以在 #plugin-general, #plugin-advanced, #中文…等频道发问。

3. 结合模板快速插入指令

当你学会 Dataview 的基本操作後,可以尝试和 Template 搭配一起使用。

例如实战案例中的「自动化汇整笔记」功能,都可以用以下模板快速插入。因为我们的需求都是找到「连结到目前这则笔记」的其他笔记,因此可以用 [[{title}]] 当作变数快速插入笔记中。

table parent-link as "父连结", file.mtime as "更新时间", file.ctime as "建立时间", status as "笔记状态"
from [[{{title}}]]
sort status desc, file.mtime desc

五、结论

这篇文章介绍了 Obsidian 神器 — Dataview 的使用方式,包含:

  • 基础的查询语法
  • 实战应用
  • 使用建议

希望大家阅读完毕後都可以试用看看这款插件。若有不清楚的地方,欢迎在下方留言与我讨论。


<<:  [Day 23] 让tinyML感受你的律动

>>:  Day 26 阿里云上运行Kubernetes 2 - ACK

爬取多个页面

这次是要一次爬取多个页面的资料,延续抓取漫画资料的程序码。因为我知道每个漫画的路由後面都是编号,所以...

Flutter基础介绍与实作-Day13 Onboarding、Login、Sign Up范例实作(1)

今天我们就利用我们之前所学的来做一个和旅游相关的Onboarding介面,事不宜迟赶快开始吧! 我想...

Kotlin Android 第11天,从 0 到 ML - Kotlin Coroutine

前言: Kotlin Coroutine , Coroutin (中文翻 “协程” )这个词在and...

Day 23 AWS的云上排队服务-SQS

想知道如何在云端上传递和处理来自使用者的网路请求讯息吗?AWS的SQS可以帮助我们做到这一点。我们往...

Day 21 - 背景 Gradient 使用

欢乐的时光总是过得特别快,不知不觉连假就要结束了,不过威尔猪也太悲催,为了铁人赛,中秋节还要在电脑...