Obsidian 核心插件数据库(Bases)之语法使用教程

数据库(Bases)是 Obsidian 官方推出的核心数据库插件,无需任何第三方工具就能把一批笔记聚合成可排序、可筛选的多种视图布局。

数据库以 .base 为扩展名保存,文件内容是符合特定模式的合法 YAML,用于描述筛选条件、计算公式和视图配置。数据本身依然存储在每篇笔记的前置元数据(Properties)中——没有私有格式,没有外部依赖,完整地延续了 Obsidian 的纯文本哲学。数据库通常通过图形界面进行编辑,但其底层 YAML 语法同样可以手动编写。本文将逐节拆解每个语法单元的用途与写法,辅以统一的示例场景,读完后可以独立编写一个功能完整的 .base 文件。


目录

  1. 数据库文件的整体结构
  2. 筛选(filters):缩小数据范围
  3. 公式(formulas):创建动态计算属性
  4. 属性(properties):管理列的显示配置
  5. 汇总(summaries):对数据列做聚合统计
  6. 视图(views):定义数据的呈现方式
  7. 三种属性类型详解
  8. 使用 this 访问上下文属性
  9. 运算符详解
  10. 类型系统
  11. 将数据库嵌入笔记与侧边栏
  12. 函数参考
  13. 常见问题与注意事项
  14. 进阶用法与联动建议
  15. 附录:阅读笔记管理数据库完整示例

1. 数据库文件的整体结构

一个完整的 .base 文件由以下五个顶层字段构成,每个字段控制数据库行为的一个特定方面:

字段作用是否必填
filters全局筛选:限定哪些文件纳入数据库范围
formulas公式定义:基于现有属性派生新的计算属性
properties属性显示配置:设置各属性在视图中的列名等信息
summaries自定义汇总公式:定义聚合统计方法
views视图定义:决定数据以何种形式呈现否(但没有视图则无法查看数据)

以上五个字段均为可选,但在实际使用中,你通常至少需要定义 filtersviews 才能得到有意义的输出。完整的数据库文件示例已放置于本文末尾附录部分,以下各节将逐一拆解每个字段的写法与用途。

📎 获取完整代码

  1. 为了提升阅读体验,完整代码已放置于本文末尾附录部分,可直接前往复制使用。
  2. 关注微信公众号:Obsidianist,回复关键词:数据库语法,后台即会自动回复完整代码文件下载地址,下载后直接将文件在 Obsidian 中打开,按教程配置即可使用。

2. 筛选(filters):缩小数据范围

默认情况下,Bases 数据库会将仓库中的所有文件纳入数据集,包括 Markdown 笔记和各类附件。与 Dataview 或 SQL 中需要显式声明数据来源不同,Bases 没有 FROMsource 子句,而是通过 filters 部分来缩小数据范围。

2.1 筛选的两个层级

有两种应用筛选的方式:一是在顶层的全局 filters 字段中定义,应用于数据库中的所有视图;二是在具体的 view 条目内定义,仅作用于该视图。这两个层级在功能上是等价的,在对视图进行求值时,它们会以 AND 方式合并——全局筛选先圈定数据范围,视图内的筛选在此基础上进一步过滤。

2.2 筛选语法结构

filters 部分接受以下两种形式:

  • 单条筛选语句:一个字符串,表达式求值为真或假。
  • 筛选对象:包含 andornot 三个逻辑关键字之一,其值为其他筛选对象或筛选语句的混合列表。这三种关键字可以层层嵌套,构建任意复杂度的逻辑组合。

简单筛选示例(仅纳入带有「project」标签的笔记):

filters:
  and:
    - file.hasTag("project")

复杂筛选示例(多条件组合,满足多种情况之一即可纳入):

filters:
  or:
    - file.hasTag("project")
    - and:
        - file.hasTag("weekly")
        - file.hasLink("年度目标")
    - not:
        - file.hasTag("template")
        - file.inFolder("归档/已完成")

⚠️ 注意(特定设置) 以上示例中的标签名、链接目标文件名和文件夹路径均为示例特定值,并非通用默认配置。

项目示例特定值通用写法/替换建议
标签名"project""weekly""template"替换为你实际使用的标签名,不含 # 前缀
链接目标"年度目标"替换为你仓库中实际存在的笔记文件名
文件夹路径"归档/已完成"替换为你的实际文件夹路径,使用正斜杠 / 分隔层级

标签名传入时不需要加 # 前缀;文件夹路径支持多级嵌套,用 / 分隔即可,路径末尾是否带斜杠均可接受。

2.3 筛选语句的两种形式

筛选语句(即列表中每个 - 项的值)可以是:

  • 基础比较表达式:使用标准算术或比较运算符对属性值进行比较,例如 "rating > 4""status != \"draft\""
  • 函数调用:调用内置函数,例如 file.hasTag()file.inFolder()file.hasLink() 等,返回值为布尔值。

筛选和公式使用完全相同的语法与函数集合,学会其中一个,另一个自然触类旁通。


3. 公式(formulas):创建动态计算属性

formulas 部分定义公式属性,公式属性是通过计算派生出来的属性,不存储在任何 Markdown 文件的前置元数据中,而是由 Bases 在展示时实时计算。公式属性可以像普通属性一样在视图中展示为列,也可以在其他公式或筛选条件中引用。

以一个阅读笔记管理场景为例,假设每篇读书笔记的前置元数据包含 rating(评分,数字类型,1–5)和 pages(总页数,数字类型)两个字段:

formulas:
  score_label: 'if(rating, rating.toFixed(1) + " 分")'
  density: "(pages / rating).toFixed(0)"

score_label 将数字评分格式化为带「分」字后缀的字符串(如 4.5 分),用于在视图中提供更可读的展示;density 计算每个评分单位对应的页数(页数除以评分),可以理解为信息密度的一种粗略衡量指标。

⚠️ 注意(特定设置) 以上公式基于笔记前置元数据中存在 ratingpages 两个属性,属于示例场景的特定配置,并非通用默认值。

项目示例特定值通用写法/替换建议
属性名 rating评分字段替换为你笔记中实际使用的数字属性名
属性名 pages页数字段替换为你笔记中实际使用的另一数字属性名
公式名 score_label / density自定义公式标识符可改为任意不含空格、不与保留关键字冲突的英文名称

公式名称将被用于在视图和其他公式中引用(例如 formula.score_label),请避免与 Bases 内部使用的保留关键字重名。

3.1 属性引用方式

你可以根据属性类型以不同方式引用属性:

  • 笔记属性:存储在 Markdown 文件前置元数据中的属性,使用 note.属性名 格式,例如 note.ratingnote.author。如果没有指定前缀,则默认为 note 属性,即 ratingnote.rating 等价。
  • 文件属性:描述文件自身元信息的属性,使用 file.属性名 格式,例如 file.sizefile.mtime。也可以直接引用文件对象本身,调用其方法,如 file.hasLink()
  • 公式属性:本 .base 文件中定义的其他公式,使用 formula.公式名 格式,例如 formula.score_label。公式可以引用其他公式属性的值,构建多层计算链,但不允许存在循环引用。

公式属性在 YAML 中始终以字符串形式存储,但其实际输出数据类型由底层数据和所用函数的返回值决定。例如,一个计算 pages / rating 的公式,输出依然是数字类型,可以继续用于数字比较和数值汇总,尽管它在 YAML 中以字符串定义。

3.2 YAML 中的嵌套引号写法

请注意,要在 YAML 字段中包含文本字面量,需要使用嵌套引号。文本字面量必须用单引号或双引号括起来,而整个 YAML 字符串值也需要用引号定界,因此外层和内层需要使用不同的引号类型:

formulas:
  # 外层单引号,内层双引号:推荐写法,适合大多数场景
  label_with_unit: 'if(weight, weight.toFixed(1) + " 千克")'
  # 外层双引号,内层单引号:同样合法,按需选择
  status_text: "if(done, 'Completed', 'In Progress')"

4. 属性(properties):管理列的显示配置

properties 部分允许存储每个属性的配置信息,目前最常用的配置项是 displayName(显示名称)。在表格视图中,显示名称用作列标题;在卡片视图中,显示名称用作字段标签。如何使用这些配置值,由各个视图类型自行决定。

沿用阅读笔记场景,为三种不同来源的属性各自配置显示名称:

properties:
  status:
    displayName: 阅读状态
  formula.score_label:
    displayName: "评分"
  file.ext:
    displayName: 文件类型

status 是笔记属性,formula.score_label 是公式属性,file.ext 是文件属性——三种属性类型在 properties 字段中的引用格式,与在筛选和公式中引用时完全一致。

有两点需要特别注意:显示名称仅用于视图呈现,不会影响筛选条件或公式计算,在筛选和公式中引用属性时,必须使用原始的属性名(如 status),而不是 displayName 中设置的自定义名称。此外,如果不在 properties 字段中配置 displayName,Bases 会直接使用属性名本身作为列标题,对于英文属性名通常已足够,只有当希望在视图中呈现中文列标题时才需要在此处配置。

⚠️ 注意(特定设置) 以上配置中的属性名(statusformula.score_labelfile.ext)和显示名称(「阅读状态」、「评分」、「文件类型」)均为示例值。请将属性名替换为自己笔记中实际使用的字段名称,显示名称按需填写即可。


5. 汇总(summaries):对数据列做聚合统计

5.1 自定义汇总公式

summaries 部分可用于定义自定义汇总公式。汇总公式会对视图结果集中某一属性列的所有值进行聚合计算,最终返回单个结果,显示在表格该列的底部统计行。

summaries:
  preciseAvg: 'values.mean().round(2)'

在汇总公式中,values 是一个固定关键字,代表结果集中所有笔记在目标属性上的值的列表。上面这个 preciseAvg 公式与内置的 Average 功能相同,区别在于将平均值四舍五入到两位小数,适合需要比整数平均值更精确的展示场景。汇总公式应返回单个 Value

请注意,这里的顶层 summaries 与视图配置中的 summaries 含义不同:顶层 summaries 用于定义汇总公式,是公式本身的声明;视图内的 summaries 用于将已定义的汇总公式分配到具体的属性列,是公式的应用。两者写法类似但位置不同,不可混淆。

5.2 默认汇总公式

除自定义汇总外,Bases 内置了一批默认汇总公式,可直接按名称在视图配置的 summaries 字段中引用,无需提前在顶层 summaries 字段中声明:

名称输入类型描述
Average数字输入值中所有数字的算术平均值
Min数字输入值中的最小数字
Max数字输入值中的最大数字
Sum数字输入值中所有数字的总和
Range数字MaxMin 之间的差值
Median数字输入值中所有数字的中位数
Stddev数字输入值中所有数字的标准差
Earliest日期输入值中最早的日期
Latest日期输入值中最晚的日期
Range日期LatestEarliest 之间的差值
Checked布尔值true 值的数量
Unchecked布尔值false 值的数量
Empty任意输入值中为空的数量
Filled任意输入值中不为空的数量
Unique任意输入值中唯一值的数量

6. 视图(views):定义数据的呈现方式

views 部分定义了数据的呈现方式。views 列表中的每个条目定义同一数据的一个独立视图,可以根据需要创建任意多个不同的视图。同一份数据可以拥有多个并列的视图,彼此独立、互不干扰——你可以为同一批阅读笔记同时创建「按分类分组的总览表」和「高分精选」两个视图,在数据库文件中通过标签页随时切换。

沿用阅读笔记场景:

views:
  - type: table
    name: "我的书单"
    limit: 20
    groupBy:
      property: note.genre
      direction: DESC
    filters:
      and:
        - 'status != "completed"'
        - or:
            - "formula.density > 30"
            - "rating > 4.0"
    order:
      - file.name
      - note.pages
      - formula.density
      - formula.score_label
    summaries:
      formula.density: Average

⚠️ 注意(特定设置) 以上视图配置基于示例库中的具体属性名(genrepagesdensityscore_labelstatus)和筛选逻辑,并非通用默认值。

项目示例特定值通用写法/替换建议
name"我的书单"替换为你希望在标签栏上显示的视图名称
limit20替换为你希望单页显示的最大行数,不限制则可省略此字段
groupBy.propertynote.genre替换为你希望用于分组的属性名
视图 filters 中的属性名statusformula.densityrating替换为你笔记中实际存在的属性名
order 中的属性名file.namenote.pages替换为你希望在视图中展示的列,顺序决定列的从左到右排列
summaries 中的属性名formula.density替换为你希望在底部统计行显示汇总的属性名

各字段的作用说明如下:

type 从内置和插件添加的视图类型中选择,当前支持 table(表格)和 card(卡片),未来将支持更多类型。

name 是视图的显示名称,会显示在数据库文件的标签栏中。当数据库以嵌入形式出现时,也可通过 #视图名称 语法指定默认显示哪个视图。

limit 限制视图显示的最大行数。适用于笔记数量较多时控制视图高度,也可用于构建「只看最近 N 条」的聚焦视图。

groupBy 指定一个属性和排序方向,对视图中的行进行分组。direction 接受 ASC(升序)或 DESC(降序)。每行在指定属性上的值相同时会被归为同一组。

filters 与全局 filters 语法完全相同,但仅作用于该视图。求值时与全局筛选以 AND 方式合并。

order 是一个属性名称列表,决定表格视图中显示哪些列,以及列从左到右的排列顺序。

summaries 将属性名称映射到命名的汇总公式,汇总公式对该列中所有行的属性值执行聚合操作,结果显示在表格底部的统计行。

视图可以添加额外的数据来存储维护状态或正确渲染所需的任何信息,但插件作者应注意不要使用核心数据库插件已经使用的键。例如,表格视图可以用它来限制行数或选择用于排序的列及排序方向;不同的视图类型(如地图视图)可以用它来映射笔记中哪个属性对应经纬度。未来,API 将允许视图读写这些值,使视图能够构建自己的配置界面。


7. 三种属性类型详解

数据库中使用三种来源不同的属性。

7.1 笔记属性

笔记属性存储在 Markdown 文件的 YAML 前置元数据中,仅适用于 .md 类型的文件。这些属性可以使用 note.属性名 格式访问,例如 note.authornote.rating;也可以省略 note. 前缀,直接简写为 authorrating——如果没有指定前缀,则默认为 note 属性。在属性名不与文件属性或公式属性冲突的情况下,简写方式更加简洁。

7.2 文件属性

文件属性指当前正在测试或求值的文件,描述文件自身的系统级信息。文件属性适用于所有文件类型,包括 Markdown 笔记和各类附件,使用 file.属性名 格式访问。

例如,筛选条件 file.ext == "md" 对所有 Markdown 文件为真,对图片、PDF 等其他文件为假。

属性类型描述
file.backlinks列表反向链接文件列表。注意:此属性对性能影响较大。如果可能,请反转查找方向并使用 file.links;且当仓库发生更改时不会自动刷新结果。
file.ctime日期文件创建时间
file.embeds列表笔记中所有嵌入内容的列表
file.ext字符串文件扩展名(不含点号,如 md
file.file文件文件对象,仅可在特定函数中使用
file.folder字符串文件所在文件夹的路径
file.links列表笔记中所有内部链接的列表,包括前置元数据中的链接
file.mtime日期文件最后修改时间
file.name字符串文件名称(含扩展名)
file.path字符串文件在仓库中的完整路径
file.properties对象文件上的所有属性集合。注意:当仓库发生更改时不会自动刷新结果。
file.size数字文件大小(字节)
file.tags列表文件内容和前置元数据中所有标签的列表

⚠️ 注意 file.backlinksfile.properties 这两个属性在仓库发生变更后不会实时刷新,页面需要重新加载才能反映最新状态。在对实时性要求较高、或仓库文件数量较多的场景下,使用 file.backlinks 时需权衡性能影响。

7.3 公式属性

公式属性是在 .base 文件本身的 formulas 字段中定义的计算属性,使用 formula.公式名 格式引用,例如 formula.score_label。公式属性可以引用其他公式属性的值,只要不存在循环引用即可。


8. 使用 this 访问上下文属性

使用 this 对象来访问文件属性。this 所指向的内容取决于数据库显示的位置。

在主内容区域直接打开时this 指向数据库文件本身的属性。例如,使用 this.file.folder 返回数据库所在的文件夹路径,可以用于筛选与数据库同处一个文件夹的其他笔记。

嵌入到另一个文件中时this 指向包含嵌入的那个笔记(即嵌入文件)的属性。例如,将 ![[书单.base]] 嵌入到「2025 年阅读计划.md」中,此时 this.file.name 返回的是「2025 年阅读计划.md」这个文件的名称,而不是数据库文件的名称。这一特性使得「随笔记上下文动态展示相关内容」成为可能——同一个 .base 文件嵌入到不同笔记中,会自动展示与该笔记语境相关的数据。

在侧边栏中打开时this 指向主内容区域中的当前活动文件。这使你可以基于活动文件创建动态查询。例如,使用 file.hasLink(this.file) 可以筛选出所有包含指向当前活动笔记链接的文件,从而在侧边栏中复现反向链接面板的功能,且比内置反向链接面板支持更丰富的列展示和自定义排序。

💡 说明 this 的行为乍看有些复杂,理解起来其实很直接:它始终代表「承载这个数据库的容器」。在主内容区,容器是数据库文件自身;嵌入时,容器是包含嵌入语句的那篇笔记;在侧边栏,因为没有固定的承载文件,改为跟随主内容区的活动文件动态变化。


9. 运算符详解

9.1 算术运算符

算术运算符对数字值执行算术运算,可在公式和筛选条件中使用。例如,radius * (2 * 3.14) 计算圆的周长。

运算符描述
+
-
*
/
%取模(求余)
( )括号,改变运算优先级

9.2 日期运算

可以通过加减持续时间来修改日期。持续时间以字符串形式表示,单位标识支持多种格式:

单位标识代表的时间单位
yyearyears
Mmonthmonths
ddaydays
wweekweeks
hhourhours小时
mminuteminutes分钟
ssecondseconds

要修改或偏移日期对象,使用 +- 运算符配合持续时间字符串。全局函数 today() 可用于获取当前日期,now() 可用于获取包含时间的当前日期时刻。以下是几个实用的日期运算示例:

  • now() + "1 day" 返回从执行时刻起正好 24 小时后的日期时间。
  • file.mtime > now() - "1 week" 如果文件在最近一周内被修改则返回 true
  • date("2024-12-01") + "1M" + "4h" + "3m" 返回表示 2025-01-01 04:03:00 的日期对象。
  • 两个日期相减可得到两者之间的毫秒差,例如 now() - file.ctime 返回文件创建至今的毫秒数。
  • 要获取包含时间的日期中的纯日期部分,使用 datetime.date()
  • 要格式化日期对象,使用 format() 函数,例如 file.mtime.format("YYYY-MM-DD") 返回 2025-05-03 这样的字符串。

9.3 比较运算符

比较运算符可用于比较数字或日期对象,也可以用等于和不等于比较任意类型的值。

运算符描述
==等于(适用于任意类型)
!=不等于(适用于任意类型)
>大于(适用于数字或日期)
<小于(适用于数字或日期)
>=大于或等于(适用于数字或日期)
<=小于或等于(适用于数字或日期)

9.4 布尔运算符

布尔运算符可用于组合或反转逻辑值,计算结果为真或假。

运算符描述
!逻辑非(取反)
&&逻辑与(两者均为真则为真)
||逻辑或(任一为真则为真)

这些运算符在单条筛选表达式内使用,与 filters 字段中的 and/or/not YAML 结构功能等价。短小的条件判断使用 &&|| 更紧凑;多层嵌套的复杂条件用 YAML 结构可读性更好。


10. 类型系统

数据库有一套类型系统,公式和筛选通过它将函数应用到属性上。了解类型系统有助于理解为何某些函数只能用于特定属性,以及为何相同的运算符在不同类型上可能有不同的行为。

10.1 字符串、数字和布尔值

字符串、数字和布尔值是「原始」值,不需要调用函数就能直接在表达式中创建和使用。

  • 字符串:用单引号或双引号括起来,例如 "已完成"'In Progress'。字符串支持 + 运算符进行拼接,例如 author + " 著"
  • 数字:直接写数字,可以选择用括号括起来以提高清晰度,例如 100(3.14)
  • 布尔值:写作不带引号的 truefalse

10.2 日期和持续时间

日期表示特定的日期,或包含时间的日期,取决于创建它们的函数或分配给属性的类型。

  • 要构造日期,使用 date 函数,例如 date("2025-06-01")date("2025-06-01 09:30:00")
  • 要修改日期,加上或减去持续时间,例如 now() + "1 hour"today() + "7d"
  • 使用比较运算符(如 ><)比较日期;两个日期相减得到毫秒差(例如,(now() + "1d") - now() 返回 86400000 毫秒)。
  • 要提取日期的部分内容,使用字段访问(now().hour)或便捷函数(now().time())。
  • 日期对象上还有许多其他字段和函数可用,例如 file.mtime.format("YYYY-MM-DD") 格式化日期,file.mtime.relative() 返回如「3 天前」这样的相对描述。

10.3 对象和列表

  • 使用 list() 函数将单个元素转换为列表。这对于可能同时包含列表和单个值的属性特别有用——用 list() 包装后可以统一以列表形式处理,避免因类型不一致导致 .map() 等列表方法调用失败。
  • 使用方括号和从 0 开始的索引访问列表元素,例如 tags[0] 返回列表中的第一个标签。
  • 使用方括号和元素名称或点号表示法访问对象元素,例如 file.properties.authorfile.properties["author"]

10.4 文件和链接

Wiki 链接(形如 [[文件名]])在前置元数据属性中会被 Bases 自动识别为链接对象,在视图中会渲染为可点击的跳转链接。

  • 要构造链接,使用全局 link 函数,例如 link("参考书目") 创建指向「参考书目.md」的内部链接,或 link("https://obsidian.md") 创建外部链接。
  • 你可以从任何字符串创建链接,例如 link(file.ctime.date().toString()) 根据文件创建日期构造一个指向对应日期笔记的链接。
  • 要设置显示文本,传入可选的字符串或图标作为第二个参数,例如 link("参考书目", "查看书目")link("参考书目", icon("book"))

文件对象可以使用 file.asLink() 转换为链接,可选传入显示文本,例如 file.asLink("打开文件")

链接可以用 ==!= 进行比较:只要两个链接指向同一个文件就视为相等;如果目标文件在查找时不存在,则链接文字必须完全相同才视为相等。链接可以与 filethis 等文件对象直接比较,例如 reviewer == thisreviewer 属性链接到当前文件时返回 true。链接也可以在列表包含检查中使用,例如 collaborators.contains(this) 筛选出 collaborators 列表中包含当前文件链接的笔记。


11. 将数据库嵌入笔记与侧边栏

11.1 嵌入到笔记正文

数据库文件可以使用标准的嵌入语法嵌入到另一篇笔记中:

![[我的书单.base]]

⚠️ 注意 嵌入时必须保留 .base 扩展名。省略扩展名后,Obsidian 会将其解析为对同名 Markdown 文件的引用,而非数据库文件,导致嵌入失败。

嵌入后,数据库在笔记正文中以交互式视图的形式渲染,读者可以直接在嵌入的视图中编辑属性值。更重要的是,嵌入状态下 this 指向包含嵌入的那篇笔记,这使得「随笔记上下文动态变化的视图」成为可能——同一个 .base 文件嵌入到不同笔记中,会自动展示与该笔记相关的内容。

如果数据库定义了多个视图,可以在嵌入语法中通过 # 指定显示特定视图:

![[我的书单.base#高分精选|高分精选]]

其中 高分精选 是视图配置中 name 字段的值。

11.2 拖拽到侧边栏

.base 文件从左侧文件列表拖拽到 Obsidian 的侧边栏(左侧或右侧均可),即可将数据库作为一个持久面板固定显示。侧边栏中的数据库在 this 行为上会跟随主内容区的活动笔记变化,是构建动态「相关笔记面板」或「增强版反向链接面板」的理想方式。


12. 函数参考

Bases 内置了丰富的函数库,可以在公式和筛选条件中调用。由于函数列表随 Obsidian 版本更新而持续扩充,以下按类别列出常用函数的概览,建议在需要使用特定函数时直接查阅 Obsidian 官方文档(obsidian.md/help/bases/functions)以获取最准确的参数说明和返回值类型。

全局函数(不依附于特定类型,直接调用):today() 获取当天日期、now() 获取当前日期时刻、date() 构造日期对象、if(条件, 真值, 假值) 条件判断、link() 构造链接对象、image() 构造图像对象(用于在视图中渲染图片)、list() 将单值包装为列表、min()max() 取多个数字中的最小/最大值。

字符串函数(在字符串值上调用):.contains() 包含检查、.startsWith().endsWith() 前后缀检查、.toUpperCase().toLowerCase() 大小写转换、.replace() 替换、.slice() 截取子字符串、.length 获取长度。

数字函数(在数字值上调用):.toFixed(n) 保留 n 位小数、.round() 四舍五入、.ceil() 向上取整、.floor() 向下取整。

日期函数(在日期值上调用):.format() 格式化输出、.date() 提取纯日期部分、.time() 提取时间字符串、.relative() 返回相对当前时刻的描述(如「3 天前」)。

文件函数(在文件对象上调用或作为筛选语句):file.hasTag() 检查文件是否含有指定标签、file.hasLink() 检查文件是否包含指向指定文件的链接、file.inFolder() 检查文件是否在指定文件夹内、file.asLink() 将文件对象转为链接。

列表函数(在列表值上调用):.contains() 检查列表中是否包含指定值、.map() 对每个元素应用表达式、.filter() 筛选满足条件的元素、.length 获取列表元素数量、.mean() 计算均值、.sum() 求和、.min().max() 取极值。


13. 常见问题与注意事项

13.1 数据库默认包含仓库中的所有文件

默认情况下,Bases 会将仓库中所有文件纳入数据集,包括图片、PDF 等非 Markdown 附件。如果只希望展示 Markdown 笔记,可以在全局 filters 中加入以下条件:

filters:
  and:
    - 'file.ext == "md"'

这样就只会显示扩展名为 md 的文件,其他类型的附件不会出现在数据库中。

13.2 含有特殊字符的筛选语句需用引号括起来

当筛选语句包含空格、比较运算符(如 >!=)等特殊字符时,整个语句必须用引号括起来,否则 YAML 解析会出错:

filters:
  and:
    - 'rating > 4'          # 正确:含运算符的语句用引号括住
    - 'status != "done"'    # 正确:双重引号嵌套时外层用单引号
    - file.hasTag("reading")  # 函数调用通常可不加外层引号,但加上更稳妥

养成对含有比较运算符的筛选语句统一加外层引号的习惯,可以避免大多数 YAML 解析错误。

13.3 行内属性(Inline Properties)不受支持

Bases 当前仅读取 YAML 前置元数据中的属性,不支持正文中用 [key:: value] 语法定义的行内属性。如果你大量依赖行内属性,这些数据将无法在 Bases 中作为列展示或用于筛选。建议将关键属性迁移到前置元数据,或对行内属性场景继续使用 Dataview。

file.backlinks 需要对整个仓库进行反向链接扫描,在笔记数量较多的仓库中会明显拖慢数据库的加载速度。如果你的目的是查找「链接到某笔记的文件」,更好的做法是将数据库拖到侧边栏,配合 file.hasLink(this.file) 筛选,性能更优且能实时跟随活动笔记变化。

13.5 公式的 YAML 存储格式与输出类型无关

公式在 YAML 中始终以字符串形式存储,但这不影响其输出类型。一个公式如果计算结果是数字,那么这个数字可以继续参与其他数字运算和数值汇总(如 AverageSum);如果公式通过字符串拼接(如加了「分」字后缀)返回字符串,则无法再对该公式属性应用数值类汇总。在设计公式时,需要根据用途决定:若需要汇总统计,保持输出为纯数字;若只需展示,可以格式化为带单位的字符串。

这两个文件属性在仓库发生变更(新增、修改、删除笔记)后不会立即刷新,需要重新加载页面才能反映最新状态。在需要实时反映仓库变化的场景中,优先选用其他文件属性(如 file.tagsfile.linksfile.mtime 等),这些属性的刷新更及时。


14. 进阶用法与联动建议

14.1 用 this 在侧边栏构建动态关联视图

将数据库拖拽到侧边栏后,配合 this 关键字可以构建出随活动笔记实时变化的关联视图。在数据库的全局筛选中写入以下条件:

filters:
  and:
    - file.hasLink(this.file)

这会筛选出所有包含指向当前活动笔记链接的文件,效果类似于 Obsidian 内置的反向链接面板,但额外支持自定义列展示、多列排序和汇总统计,信息密度更高。

⚠️ 注意(特定设置) 上述筛选条件假设你希望查看「有哪些笔记链接到了当前活动笔记」,这是一种特定的使用场景,并非通用默认配置。根据需求,你也可以换用 file.folder == this.file.folder(展示同文件夹下的所有笔记)或 file.hasTag("weekly") 等其他条件来构建不同用途的动态面板。

14.2 多视图结合不同筛选覆盖多种场景

同一个 .base 文件中可以定义多个视图,每个视图有独立的筛选、排序和汇总配置,但共享全局筛选圈定的数据范围。以阅读笔记管理为例,可以在一个文件中同时维护:「全部书目」视图(不设额外视图级筛选)、「正在阅读」视图(追加 status == "reading" 筛选)和「高分精选」视图(追加 rating >= 4.5 筛选)。用户可以通过标签页在三个视图间快速切换,而全局的「只显示 Markdown 文件」筛选对三个视图同时生效,无需重复配置。

14.3 嵌入 + this 构建随上下文变化的动态模板

将同一个 .base 文件嵌入到多篇「项目主笔记」中,配合 this.file.folder 可以让每篇主笔记的嵌入视图自动展示其所在文件夹的子笔记:

filters:
  and:
    - 'file.folder == this.file.folder'
    - 'file.ext == "md"'
    - 'file.name != this.file.name'

最后一行 file.name != this.file.name 是为了将主笔记自身排除在视图之外,避免数据库在自己的嵌入视图中显示自身。

⚠️ 注意(特定设置) 以上筛选条件假设项目主笔记与其子任务或子笔记存放在同一文件夹中,这是一种特定的库结构约定。如果你的库结构以标签或链接而非文件夹来组织项目,筛选条件需要相应调整为基于标签或链接的判断逻辑。

14.4 与 Properties 核心插件配合使用

Bases 和 Properties 核心插件是天然的搭档。Properties 面板提供了属性的图形化输入界面,能确保属性值的格式统一(例如日期属性始终以正确的 YYYY-MM-DD 格式存储);Bases 则读取这些属性进行筛选和计算。在 Properties 插件中为每个属性明确指定类型(文本、数字、日期、复选框等),不仅有助于输入时的格式校验,也能让 Bases 在进行类型相关的函数调用时更准确地推断数据类型,避免因类型不匹配导致的公式计算异常。

14.5 展望:即将到来的功能

根据 Obsidian 团队公布的路线图,Bases 后续计划增加的功能包括:更多视图类型(地图视图已在部分版本中实验性提供,通过安装社区 Maps 插件后即可在 Bases 中使用)、分组(Grouping)功能、插件 API 支持(允许社区插件扩展 Bases 的函数库和视图类型)以及 Obsidian Publish 支持。这些功能将在 Bases 进一步成熟后陆续落地,届时其使用场景和能力边界都将进一步扩展。


附录:阅读笔记管理数据库完整示例

以下是一个以「阅读笔记管理」为场景的完整 .base 文件示例,涵盖全局筛选、公式定义、属性显示名称配置、自定义汇总公式和视图定义,可作为学习参考或在改造后用于自己的仓库。

假设每篇阅读笔记的前置元数据包含以下字段:rating(评分,数字,1–5)、pages(总页数,数字)、status(阅读状态,文本,如 readingcompletedwishlist)、genre(分类,文本,如 fictionnon-fictionscience)。

filters:
  or:
    - file.hasTag("reading")
    - and:
        - file.hasTag("book")
        - file.hasLink("年度书单")
    - not:
        - file.hasTag("book")
        - file.inFolder("归档/已读")
formulas:
  score_label: 'if(rating, rating.toFixed(1) + " 分")'
  density: "(pages / rating).toFixed(0)"
properties:
  status:
    displayName: 阅读状态
  formula.score_label:
    displayName: "评分"
  file.ext:
    displayName: 文件类型
summaries:
  preciseAvg: 'values.mean().round(2)'
views:
  - type: table
    name: "我的书单"
    limit: 20
    groupBy:
      property: note.genre
      direction: DESC
    filters:
      and:
        - 'status != "completed"'
        - or:
            - "formula.density > 30"
            - "rating > 4.0"
    order:
      - file.name
      - note.pages
      - formula.density
      - formula.score_label
    summaries:
      formula.density: Average

⚠️ 注意(特定设置) 以上配置基于示例库的具体字段名和文件夹结构,并非通用默认值。请根据自身库结构替换标签名(readingbook)、链接目标文件名(年度书单)、文件夹路径(归档/已读)以及所有属性名称(ratingpagesstatusgenre)。

📎 获取完整代码

  1. 以上即为完整代码,可直接复制使用。
  2. 关注微信公众号:Obsidianist,回复关键词:数据库语法,后台即会自动回复完整代码文件下载地址,下载后直接将文件在 Obsidian 中打开,按教程配置即可使用。