移除 org-roam 等工具,尝试自己建立笔记反向链接查询

最近因为 emacsql 的修改,就干脆把 org-roam 直接给删掉了。

不想用 org-roam/denote/zk 这类工具的原因简述 org id 这样的方案需要至少扫描一遍相关文档,并维护一个 locations 才能工作。

org-roam 又有点太重了,里面很多功能其实基本用不上。

denote / zk 这样自定义链接类型的方案,因为本来就是 org 到 org 的内部链接,却单独建了一个链接类型。这导致原本非常基础的单向链接也要依赖于外部工具也能工作。

简单的方案

把笔记的链接全部成了基于文件路径加 custom-id 的形式,也就是 org 本身就支持的到文件内 headline 的链接方案。好处是仅依靠 org-mode 本身就能使正向的链接工作。文件的链接用的是相对路径(org-link-file-path-typerelative,adaptive 从父向子很好用,但子向父会强制转成绝对路径,如果有人加个基于 project-rootorg-directy 的相对就好了)。

基于 org-ql 就简单实现了一下这个功能:

(defun +org/ql-notes (query)
  "`org-ql-search' in `+org-note-dir' recursively with QUERY."
  (interactive "squery: ")
  (org-ql-search
    (org-ql-search-directories-files
     :directories (list +org-note-dir)
     :recurse t)
    query
    :title "Query Notes"))

(defun +org/ql-notes-backlinks (query)
  "Search QUERY in linking content.

QUERY is the link content.  When calling interactively, it is read at current
point.  You can also use prefix arg to query file instead of current headline.

For performance reason, regexp doesn't support in this function.
Please use `+org/ql-notes' manually."
  (interactive (list (+org--notes-get-link-search current-prefix-arg)))
  (+org/ql-notes `(link ,query)))

(defun +org--notes-get-link-search (&optional file?)
  "Get search content for link in `+org-note-dir' at current link point.

If FILE? is non-nil, it will search filename only."
  (let* ((link-block (substring-no-properties (org-store-link nil nil)))
         (elements (org-element-parse-secondary-string link-block '(link)))
         (link-props (cadr (car elements)))
         (filepath (file-relative-name
                    (plist-get link-props :path)
                    +org-note-dir))
         (opt (plist-get link-props :search-option))
         (opt-str (if (or file? (not opt) (string-empty-p opt))
                      ""
                    (format "::%s" opt))))
    (format "%s%s" filepath opt-str)))

不知道有没有什么优化空间?

性能

因为 org-ql 完全是依赖 org 库来实现的,文件非常多的情况会很糟(相当于每次要在 emacs 里开文件,然后 org 对这个文件扫描、初始化解析数据),然后再查询。

不过后来试了一下 org-ql 对个人来说够用了(基本上来说,不用 org-ql 里的正则,感觉性能够用)。

本来有考虑像邮件那样写个外部工具来做检索。文档本身就是纯 org 原生的内容。然后查询时,可以允许每次使用不同的基目录,查找时只要把所有文件过一遍,写个 parser 解析文档,拆成树。只要开个基于文件的并行,不需要建库应该就能满足大部分场景。还能顺便加上什么表格内容查找、图像说明什么的很复杂的功能。

其它

org-ql 的作者好像也在做一个基于 org-ql 的关系图生成。不过是基于 graphviz 的,我应该是不会去使用了。

1 个赞

可以参考之光的项目:

https://archive.casouri.cc/note/2020/simple-(back)-links-in-any-file/index.html#Introducing-bklink.el

可以试试orgrr ,用的是emacs默认的文件引用方式。

orgrr 是一个文件为单位的。我现有的笔记是放在子节点里的。

可以试试我写的缩水版的 org-roam ,用的是Emacs自带的sqlite。只保留了节点信息存数据库的功能。

已经初步支持让org-agenda查询的时候用数据库了,目前实现的比较烂,速度还没不用sqlite快。

并且整合了一个乞丐版的org-noter,这样笔记的位置是从数据库里查,而不是一个个文件找过来。

我想实现org-ql类似的功能,但是org-ql代码好高级,看不懂,不知道怎么实现开了数据库就用数据库查,不开继续保留原来的方式。