混用 org-ql、columnview、org-roam、org-capture、org-super-links 塑造我的笔记流程

我是一个勤快做笔记的人,也喜欢试用市面上的各种笔记工具,当前笔记 3 大件,obsidian、notion、logseq 我都试用过了。可以说他们都各有擅长,上个月我完整地看了几个有代表性的 workflow 视频,有一些特性令我心痒痒的:

1、notion 的 dashboard,可以方便地让人查看各类事项的进度,以及做好随时收集自己看过的书、电影,外出游玩,方便将人的生活拆分成不同的维度,看到会有一种丰满感; 2、obsidian 丰富的插件,将 obsidian 拓展成笔记版的 Emacs; 3、logseq 的 query,logseq 不提倡不停地分不同的文件进行记录,而是每天都在一个页面上记录,但通过内置的 query,或者用户写的 query,对特定内容进行自动化的整理;

但是,notion 数据不能本地存储,obsidian 里的高级玩法也需要用户写代码,如果这样我还不如用回自己熟悉的 emacs,logseq 这种直接进行自动化整理的方式,实际上是将笔记的反人类部分给磨平——但也去掉了笔记的意义,因为人必须得反思,才能进行有效的判断,结果把反人类部分磨平了之后,人容易变成笔记机器,更大概率的患上了笔记松鼠症,而非……会思考的动物了。

受到笔记 3 大件的启发,我开始寻找 emacs 上类似的替代方案,可以做到 notion 的 dashboard,又能实现 logseq 的 query。我也在社区发帖提问, TomoeMami 提到了 org-ql 这一工具。所以,我花了大概几天的业余时间对该工具进行了钻研,期间为了探明 org-mode 的 dynamic block 功能跑到开发者的 github 上提 issue,在社区里发帖,最后还到暗无天日的 github 上询问。我通过 org-ql 了解到 org-mode 的 columnview 功能,然后发现笔记里的 dashboard 完全可以交给 columnview 来完成。感谢在此探索期间,向我提供过帮助的朋友们。

写了这么多,也该分享我现在的笔记方法:

我的笔记分成 4 类:知识类、事实类、项目类、记录类。

  • 知识类:以领域区分。比如行业,市场营销等。
  • 事实类:影响到某些事情判断的事件、数据。比如,青年的咖啡消费比例,2022年获投案例数量等。
  • 项目类:手中正在进行的项目,一般一个项目一个文件,进行长期的追踪和记录。
  • 记录类:这主要是记录自己看过的书、电影,听过的音乐,旅游过的地方等。

我为以上 4 类笔记,搭配了不同的流程和形式。

  • 知识类:

遇到新的概念,我直接用自己定义的 org-roam 的 capture 模板进行记录。只需要 org-roam-find-node 功能直接输入新名词,然后选择对应的模板,记录下来,同时再笔记内,用 org-roam-insert-node 来创建笔记与笔记之间的关联。

通常情况下,我很少用到 backlink,只有我专门进行回顾的时候,才会启用 backlink。

以下是我设计的 org-roam-capture 模板——因为我发现 org-roam-capture 与 org-capture 行为有区别,前者是在输入了笔记标题之后,才选择笔记模板;而后者则是先选择模板,在进行标题或笔记的记录。

以下是我使用的 org-roam-capture 模板,对应特定分类的笔记,会放在不同的文件夹里,会让人更清晰一些:

(setq org-roam-capture-templates '(
                ("d" "default" plain "%?"
                 :target (file+head "%<%Y%m%d%H>-${slug}.org"
									"#+title: ${title}\n#+filetags: \n")
                 :unnarrowed t)
                ("b" "book notes" plain "%?"
                 :target (file+head "book/book%<%Y%m%d%H>-${slug}.org"
									"#+title: ${title}\n#+filetags: :bookreading: \n\n")
                 :unnarrowed t)
                ("c" "company" plain "%?"
                 :target (file+head "company/company%<%Y%m%d%H>-${slug}.org"
									"#+title: ${title}\n#filetags: :compnay: \n\n")
                 :unnarrowed t)
                ("i" "industry" plain "%?"
                 :target (file+head "industry/industry%<%Y%m%d%H>-${slug}.org"
									"#+title:${slug}\n#+filetags: :industry: \n\n")
                :unnarrowed t)
				("m" "marketing" plain "%?"
                 :target (file+head "marketing/marketing%<%Y%m%d%H%M%S>-${slug}.org"
									"#+title: ${title}\n#+filetags: :marketing: \n\n")
                 :unnarrowed t)
				("p" "project" plain "%?"
                 :target (file+head "project/project%<%Y%m%d%H>-${slug}.org"
									"#+title: ${title}\n#+filetags: :project: \n\n - tag ::")
                 :unnarrowed t)

				("r" "reference" plain "%?"
				 :target (file+head "<%Y%m%d%H>-${slug}.org"
									"#+title: {$title}\n%filetags: reference \n\n -tag ::")
				 :unarrowed t)))
  • 事实类:

事实类笔记内容会比较零散,通常也不适合单独记录在单个文件里,而且事实类笔记往往容易打脸,但它也需要存在,以便我在做咨询 PPT 的时候,对其中内容进行引用。

针对这种比较零散的笔记,我的做法是,把它们一股脑的放进一个名为 readlog.org 的文件里,每一条信息是就是一条 heading,然后添加 tag 进行区分。

最后,我再用 org-ql-search 功能,加上它的 query 语法,把我关注的 tag 全部抓出来之后,再保存到 org-ql-view 视图里。这样,当我需要查阅时,只需要打开 org-ql-view,然后再唤出对应的视图就行——不过,其实也没那么麻烦,我相信大部分 emacs 用户打开了 buffer 之后是不关的,我也是,所以唤出一次之后,只需要进入 buffer-list 里搜索对应的标题即可。关于 org-ql 的 query 语法,我粗略的翻译了一下,也发到社区里了,org-ql 讨论帖

针对我日记中的一些记录,我也是这么处理的,我这个人比较重视朋友,所以说,哪一天跟哪些朋友相聚,都进行记录,我现在的做法是,在对应的 heading 旁边添加「朋友」这个标签,这样子通过 org-ql 就可以一下子检索出来,直接保存成视图,就可以知道一段时间里,分别和哪些朋友相聚。

  • 项目类:

我手中会并行多个项目,也面向不同的行业,各自有各自的进度。

一个项目对应专门一份 org 文件。在这里面我会以项目日志的方式记录项目进度,总结项目中可能出现的问题,草拟一些对应的方案。为了方便自己回顾不同的项目情况,我比较需要一个 dashboard 让我可以快速的统揽项目的状况,进入到对应的笔记。这时候如果有 dashboard 最为方便。

我用 org-mode 的 columnview 来完成这一工作。不采用 org-ql 的原因是,它在输出对应的表格时,无法识别 org-mode 的链接语法,另外,不像 columnview 可以添加 :file 语句,可以直接调用另外一个文件里的内容。

由于我是用单一文件来记录一个项目里发生的所有事情,因此就不适合用 org-roam 的双链来对不同节点的关联。

在此,我运用 org-super-links 来创造节点与节点之间的关联——

比如说,我的 项目.org 里,会分别日志(log),和下一步(任务),通常是写完日志之后,确定了下一步行动,因此可以用 org-super-links 来创建日志与任务之间的关联。

  • 记录类:

我会记录自己阅读过的书,看过的电影,和听过的音乐,以及旅游。

我会混用 org-capture 和 org-roam-capture,来记录自己阅读过的书籍——

首先,我用 org-captuer 将我新阅读的书添加到我的书籍阅读记录的文件里,我设计了好几个 property,用来记录对应的状态。如果这本书有值得制作笔记的部分,我会用 org-roam-capture 来新建一个笔记。

电影、音乐、旅游等记录,都采用类似的方法。

总结

哪些笔记应该零散记录,哪些笔记应该集中记录,一直是知识管理界,笔记界的讨论话题。

我认为,世界上的笔记类型很多,当它对个人而言只是一个个零散的点时,它就应该是一个个零散的点,之后有机会再把它们串起来。

目前这套笔记方法,我认为优点就是零散笔记,有了专门集中的地方,而且通过工具来检索和集中展示;而不是用 org-roam 原有的一个文件一条笔记的方式,后者会令文件过度破碎,反而在检索和检阅的层面增加了很大的难度。

在形成这个笔记方法的过程中, 我体会到 emacs 的自由度,emacs 把自己当做方法的工具,只要有想法,即便不懂 emacs-lisp 来调用高端复杂的功能,但通过搭积木和简单的语法,也能创造出适合自己的工具。

26 个赞

为什么 org-roam 不适合在一个文本里做关联 ?我理解org-roam 只是在原生的 id 链接上加了一个反向链接的 mode ,需要就可以激活来查看,另外还启动一个数据库以提供结点 cache 的功能,使得动态搜索和可视化之类的更高效,它的功能都是外挂的,至于链接本身都是 org-mode 提供的语法和跳转机制,因此说 org-roam 不适某种场景的链接,似乎在说 org-mode 里的某种链接不适合这个场景(因为你把 org-roam 删了,id 链接还是写在文件里,只是失去了动态查看反向链接的功能而已)。

另外能否介绍一下 org-super-links 使用场景是什么,我看说明似乎就是把反向链接显式地写在 org 文件(比如drawer)里?作为对比, org-roam 的用单独的 org-roam buffer 来显示。

这属于外部信息,和内部信息的区分。

项目文件,里面也可以用 org-roam 来创造笔记和笔记之间的链接,但,org-roam 所创造的链接,属于项目外部信息,项目文件可以引用外部笔记。

打个比方,我会在项目笔记里,整理方案的大纲,以及搜集所需要的资料,这时候,我可以在项目文件里,直接通过 org-roam 来链接之前记录过的笔记,或者直接在上面记录调查过程中所产生的笔记。这一类一般属于知识性的。

但项目内部信息,一般属于流程性的,比如说,我记录了日志,然后产生了一项任务,运用 org-super-links 来进行内部链接就对了,没必要体现在 org-roam 的全局,不然 backlink 就很乱,没必要增加信息熵。

我自己也有这类需求,比如说, org-roam 只用来连接知识概念,而不希望把做事情的 TODO 类 header 也纳入。

但我理解,你只要用 [[id:org-id][header]] 这种形式的链接,都会被 org-roam 缓存起来,除非这个文件不在 org-roam 扫描的目录下。或者用别的形式的 link, 但我看 org-super-links 也是通过 id 来链接的,这不能避免这个链接不被 roam 数据库读取吧

不,org-super-links 不是通过 id 来链接。

我刚才测试,没有出现你说的情形。

关于 notion 的 dashboard,我之前搜索了很久,想看看 emacs 里面有什么好的替代。org-ql 能够实现一部分功能。org-roam 记笔记虽然方便,但可视化太不行了,虽然说有什么 backlink,但实际上链接什么的没多少用,大部分笔记都是独立的,用 tag 管理更方便。最近想实现一个功能,能够把最近创建的笔记按创建时间排列在一个列表里面,像一些 wiki 的 page stream 一样,也算是一种 dashboard。但还没找到有什么办法能够实现 :frowning: image

就是用 org-mode 的 dynamic block 功能,命令是 columnview,推荐你以下资料:

  1. Capturing column view (The Org Manual)

  2. 使用 org-mode columnview 生成任务列表 - 暗无天日

  3. 请教如何令 Org-mode 的 dynamic block 展示表格 · Issue #213 · lujun9972/lujun9972.github.com · GitHub

但如果是排列 org-roam 的 node 的话,应该还是需要自己 hack 的吧,我理解这里 dynamic block 只支持排列 headline。

配列 org-roam 的 node,用 org-ql 的话,应该无法直接输出表格。所以我用的方式就比较 ticky 一点:

  1. 用 org-roam 生成 index 笔记,比如 书籍阅读记录.org
  2. 然后在配置好 org-capture,这里要注意的是,是用 org-mode 内置的 capture,做好抓取记录的模板,要设置对于的 property,比如:
(add-to-list 'org-capture-templates
			 '("lb" "书籍阅读记录" entry (file "~/……/书籍阅读记录.org")
			   "* %^{书名}\n :PROPERTIES:\n:Author: %^{作者}\n:Category: %^{类别}\n:Added: %t\n:Vote: ⭐️⭐️⭐️⭐️⭐️\n:Notelink:\n:END:\n\n"))

每天添加一笔相关的笔记,就相当于先在 index 文件里,添加一个记录。

然后,再用 org-roam-capture 来添加对应的笔记链接,这样子可以直接使用 columnview 来生成表格。

这不是一个非常完美的解决办法,如果你不坚持用表格来区分的话, 我觉得 org-ql 的 org-ql-search 和 org-ql-view 功能可以比较好的满足你。因为你可以用 org-ql-search 定义你的视图类型。

笔记过于 零散 的这种状态我也经历过,最终通过把笔记文件直接放进数据库(不用纯文本)解决,实际笔记依旧是零散的,但人的主观上没有这种感觉。

麻烦的地方就是搜索要写sql语句,但在搜索结果排序方式上就比较自由了,如按创建时间排,按最后修改时间排,按标题排,分类排。比如我的 org文件首页 是用表格展示所有分类,但分类的排序是由此分类下所有文章的最后修改时间来决定那个分类排在最前面。

你只是公开了 emacs 端的代码,但本地服务器端是没公开的吧。或许楼上的 @patrolli 会感兴趣。

这个以后应该会全部公开的,emacs端代码除非是操作数据库部分也用elisp,否则应该不会在改了,所以先发了出来,而服务端比较麻烦,经常在改动中,最近甚至把数据库结构改了,然后遇到了麻烦,暂时只好让代码同时兼容两种数据库结构都能跑起来。

如果我确定已经稳定可用,而不是各种问题bug无尽,那我肯定会把服务端也发出来的

哦,我一直以为你的方案是 emacs 端 + 本地服务器端 一起配合才行。我对笔记数量和添加日期本身没有特别的记录偏好,反倒是楼上的 @patrolli 看上去比较需要。

反倒是我明确认为是用于「统计」的笔记,类似书籍阅读记录这种,我是主动去完成这个过程,不认为需要用到被动统计。

你可以认为,我任何时刻都在做筛选。并非所有的书籍、电影、音乐都可以进入到我的统计页面里。统计页面里若评价不够高的,也不值得我为此单独创建笔记。

服务器端就是一个网站,用apache搭建的,换成任何支持php的web服务器都可以,最初是不想写htm+css+js了,就让org-mode来做了网站前端。

用elisp来操作数据库我感觉自己搞不定,于是想到了这种办法,如果能搞得定确实没必要在依赖另一个服务器端

orgcms 我觉得是个很有意思的想法,祝你早日开发出稳定的服务器端

最新版 org-roam-buffer 能显示 backlink 的 header 内容,但是无法点击访问。一路过来,org-roam 总是会出各种小毛病。叹!

楼主的笔记系统里面“双链”功能用得少,但是却用了 org-roam 、org-super-links 两个专门主打“双链”功能的包,为什么呢?(我的笔记系统目前主要分为日常速记、常规笔记、文献、日程几个板块,也可以说是几个文件夹,但它们都是相关联的,因为我用 org-roam 统一管理。而至于搜索、org-mode的相关功能都是可以拿来就用的,与“双链”的功能并不矛盾。)

感谢楼主分享 dashboard 、org-ql-viem 相关的内容,这正是我的笔记系统所缺的。

主要是 org-roam 里,可以快速输入对应的笔记 node,这个功能我还是很需要的,因为我虽然不怎么使用 backlink 来检查,但我会把尽量把相关的 node 联系在一起。

也就是说,我会建立双向链接关系,只不过,日常使用中,不经常使用 backlink 来查看。