引言
Obsidian 是一款受到全球用户热爱的强大知识管理工具。它的功能强大而灵活,但就像所有功能丰富的工具一样,Obsidian 也有它的挑战,很多用户在海量插件和复杂的系统设置中迷失了方向,知识库越做越复杂,将越来越多的精力花费在整理而非是考上。
这篇博客的目的就是向大家介绍如何用 Obsidian 搭建一个既简单又灵活的金字塔式知识库。这样的结构不仅能保持知识库的整齐有序,还能灵活地进行扩展和调整。
点击链接可以直接查看示例知识库。
知识库搭建原则
简单性
知识库是为了减轻记忆负担,帮助人们更好的思考。要做到这一点,最重要的原则就是保持简单。过分复杂的设置和分类会增加学习成本,而且可能导致日后的使用效率低下。我们的目标是尽可能减少插件的使用,专注于内容的创作和整理,而不是不断学习和调整工具的使用方法。
同时在也要避免繁琐的重复操作,以节省时间和精力。
灵活性
灵活性是另一个关键原则。知识库的内容和需求随时间而变化,所以构建一个易于调整和扩展的知识库非常重要。我们需要的是一个能够随着新信息的加入而自然演化的系统,而不是一成不变的框架。灵活性确保了知识库能够适应不同用户的需求,以及不断变化的信息结构。
结构化
“结构是记忆的支架。” 我们需要建立一套清晰、有序的信息存储和检索系统,来帮助我们快速找到所需信息,并且保持知识库的整体连贯性和一致性。大量的实践和经验表明,纵向的金字塔结构是最有效的结构之一。
搭建步骤
设置 Obsidian
在 Obsidian 中,我们的目标是用尽可能少的工具实现高效的知识管理。为此,我们主要依赖两个功能:Property 和 Dataview 插件。这两个功能能帮助我们创建清晰的结构,同时保持系统的简单性。
- Property:这个功能允许我们在笔记中设置属性和 metadata。
- Dataview 插件:Dataview 插件是 Obsidian 中的一个强大工具,它允许我们基于笔记的属性进行高级查询和视图生成。需要在设置中勾选 dataview 插件的 Enable JavaScript Queries.
笔记格式和模板
- 在 Properties 中使用“parent”属性:为笔记设置一个或多个父笔记。这不需要非常精确,但可以帮助我们理解笔记之间的关系。Parent 类型需要设置为 list,并且使用“[[”来输入笔记标题,输入完成后按下回车。
- 使用 Dataview 查询子笔记:我们可以利用 Dataview 插件来查询和展示一个笔记的所有子笔记。

- 在必要时使用 Dataview 生成完整子笔记目录:对于较高层次的目录,如项目或领域,我们可以使用 Dataview 生成其下所有子笔记的目录,以便形成整体印象,并快速访问和浏览。

Dataview 代码
使用如下代码块在页面中查询子页面,并显示为列表
```dataview
LIST
WHERE
contains(file.frontmatter.parent, "[[" + this.file.name + "]]")
```使用如下代码块在页面中查询所有子页面和子页面的子页面,并以层级的方式显示为表格。需要在设置中勾选 dataview 插件的 Enable JavaScript Queries.
```dataviewjs
function findChildren(pageFile, maxDepth = 99, depth = 0, parentChildren = null) {
let allChildren = [];
if (depth >= maxDepth){
return allChildren;
}
let pageName = pageFile.file.name;
let children = dv.pages()
.where(p => p.file.frontmatter.parent && p.file.frontmatter.parent.includes("[[" + pageName + "]]"))
.map(p => ({ page: p, depth: depth }));
if (parentChildren != null) {
parentChildren[parentChildren.length - 1].isLastChild = children.length === 0;
}
children.forEach((child, index) => {
child.isLastChild = index === children.length - 1; // Mark if it's the last child
allChildren.push(child);
allChildren = allChildren.concat(findChildren(child.page, maxDepth, depth + 1, children));
});
return allChildren;
}
function displayHierarchy(children, showDepth = 99) {
let rows = [];
children.forEach(child => {
let prefix = "";
if (child.depth == 0){
prefix = "### ";
}
else if (child.depth == 1){
if (child.isLastChild){
prefix = "└── ";
}
else{
prefix = "├── ";
}
}
else{
if (child.isLastChild){
prefix = "" + "│ ".repeat((child.depth - 1) * 1) + "└── ";
}
else{
prefix = "" + "│ ".repeat((child.depth - 1) * 1) + "├── ";
}
}
let linkPath = child.page.file.path;
let fileLink = dv.fileLink(linkPath, false, "Link")
let suffix = child.isLastChild ? " (Final Page)" : "";
if (child.depth <= showDepth){
rows.push([prefix + child.page.file.name, fileLink]);
}
});
return rows;
}
let currentPageName = dv.current();
let childPages = findChildren(currentPageName);
dv.table(["Child Pages", "Link"], displayHierarchy(childPages));
```PS:可以调整上述代码中的 findChildren 的参数 maxDepth,以仅显示一定层级的页面。比如讲 maxDepth 设置为 2,则只显示 2 层子页面。
示例
我的工作流
新建页面与设置父页面
在 Obsidian 中新建页面时,我们可以为其指定一个或多个父页面。这个过程不需要过分精确,主要目的是标记这个新页面在知识库中的大致位置。例如,如果你正在写一篇关于某个特定项目的笔记,你可以将这个项目的主页面设为父页面。这种灵活性允许用户在初步构建知识库时快速行动,随后再根据需要进行细致的整理。
如果是待处理的页面,将父页面设置为 inbox 或者 todo。
整理父页面
当某个父页面下子页面较多且明显不属于同一层级后,再进行分组和整理。
比如 PKM 下有如下子页面,比较凌乱。

通过将类似的概念分到一类,并为分类新建页面以及调整层级,得到如下整理后的目录。

示例知识库
这是一个简单的示例,顶层页面是目录页,其下包括 Database、Areas 和 Projects。

优点
全局视野
这种结构允许用户在文件头部直观地看到其上级和下级页面,并且可以查看树状的子页面结构,从而更容易形成对整体内容的印象。
在传统的 MOC(Map of Content)页面维护方式中,用户需要依赖外链和回链来识别上下级关系,但这种方法往往混杂着其他横向的链接,使得全局视野变得模糊,难以捕捉知识库的整体结构。
灵活
当用户想更改笔记层级时,只需要打开指定笔记,调整 parent 属性即可。
简单
不需要使用文件夹和标签。可以秉承极简的原则,不使用这些功能;或者留作它用。
结语
这篇博客简单探讨了如何使用 Obsidian 来打造一个既简单又有效的金字塔式知识库,希望这些内容能够对大家有所启发,提供一些实用的思路。
读者朋友们可以根据自己的实际需求,灵活调整和优化知识库的结构。每个人对于知识管理的需求各不相同,Obsidian 强大而灵活的功能,正好能够满足这些多样化的需求。通过本文,如果能给大家带来一些新的思考,或者对于如何更好地利用 Obsidian 有所帮助,那就再好不过了。
