创建与编辑带有视图(views)、过滤器(filters)、公式(formulas)及汇总(summaries)功能的 Obsidian Bases(`.base` 文件)。当需要处理 `.base` 文件、为笔记创建类似数据库的视图,或者用户在 Obsidian 中提到 Bases、表格视图(table views)、卡片视图(card views)、过滤器或公式时使用。
Obsidian Bases Skill
工作流程
- 创建文件:在 vault(仓库)中创建一个包含合法 YAML 内容的
.base文件 - 定义作用域:添加
filters筛选需要显示的笔记(按标签、文件夹、属性或日期过滤) - 添加公式(可选):在
formulas部分定义计算属性 - 配置视图:添加一个或多个视图(
table、cards、list或map),并用order指定需要显示的属性 - 校验格式:确认文件为无语法错误的合法 YAML。检查所有引用的属性和公式是否存在。常见问题包括:包含 YAML 特殊字符的字符串未加引号、公式表达式中引号未配对、以及在未于
formulas中定义X的情况下引用了formula.X - 在 Obsidian 中测试:在 Obsidian 中打开该
.base文件,确认视图正常渲染。若显示 YAML 错误,请参考下方的引号排查规则
Schema 规范
.base 文件使用 .base 扩展名,且必须包含合法的 YAML 内容。
# 全局过滤器适用于 Base 中的所有视图
filters:
# 可以是单个过滤器字符串
# 也可以是仅包含【一个】键(and、or 或 not)的嵌套过滤器对象
and:
- 'status == "active"'
- not:
- 'file.hasTag("archived")'
# 定义可在所有视图中复用的公式属性
formulas:
formula_name: 'expression'
# 配置属性的显示名称与相关设置
properties:
property_name:
displayName: "Display Name"
formula.formula_name:
displayName: "Formula Display Name"
file.ext:
displayName: "Extension"
# 定义自定义汇总公式
summaries:
custom_summary_name: 'values.mean().round(3)'
# 定义一个或多个视图
views:
- type: table | cards | list | map
name: "View Name"
limit: 10 # 可选:限制结果条数
groupBy: # 可选:对结果进行分组
property: property_name
direction: ASC | DESC
filters: # 视图级过滤器,遵循相同的规则
and:
- 'status == "active"'
order: # 按顺序显示的属性列表
- file.name
- property_name
- formula.formula_name
summaries: # 将属性映射到汇总公式
property_name: Average
过滤器语法
过滤器用于精细筛选结果,既可应用于全局,也可单独作用于特定视图。
过滤器结构
# 单个过滤器
filters: 'status == "done"'
# AND - 必须同时满足所有条件
filters:
and:
- 'status == "done"'
- 'priority > 3'
# OR - 满足任意条件即可
filters:
or:
- 'file.hasTag("book")'
- 'file.hasTag("article")'
# NOT - 排除符合条件的项目
filters:
not:
- 'file.hasTag("archived")'
# 嵌套过滤器
filters:
or:
- file.hasTag("tag")
- and:
- file.hasTag("book")
- file.hasLink("Textbook")
- not:
- file.hasTag("book")
- file.inFolder("Required Reading")
过滤器运算符
| 运算符 | 描述 |
|---|---|
== |
等于 |
!= |
不等于 |
> |
大于 |
< |
小于 |
>= |
大于等于 |
<= |
小于等于 |
&& |
逻辑与 |
|| |
逻辑或 |
| <code>!</code> | 逻辑非 |
属性
三种属性类型
- 笔记属性 - 来自 frontmatter 属性:
note.author或直接写author - 文件属性 - 文件元数据:
file.name、file.mtime等 - 公式属性 - 计算得出的动态值:
formula.my_formula
文件属性参考
| 属性 | 类型 | 描述 |
|---|---|---|
file.name |
String | 文件名 |
file.basename |
String | 不含扩展名的文件名 |
file.path |
String | 文件的完整路径 |
file.folder |
String | 父级文件夹路径 |
file.ext |
String | 文件扩展名 |
file.size |
Number | 文件大小(字节) |
file.ctime |
Date | 创建时间 |
file.mtime |
Date | 修改时间 |
file.tags |
List | 文件中的所有标签 |
file.links |
List | 文件中的内部链接 |
file.backlinks |
List | 反向链接(指向当前文件的笔记) |
file.embeds |
List | 笔记中嵌入的内容 |
file.properties |
Object | 所有 frontmatter 属性 |
this 关键字
- 在主编辑区:指向 base 文件本身
- 被嵌入使用时:指向包含该嵌入文件的宿主笔记
- 在侧边栏中:指向主编辑区中的当前激活文件
公式语法
公式可通过属性计算出动态值,在 formulas 区域中定义。
formulas:
# 基础算术运算
total: "price * quantity"
# 条件逻辑判断
status_icon: 'if(done, "✅", "⏳")'
# 字符串格式化
formatted_price: 'if(price, price.toFixed(2) + " dollars")'
# 日期格式化
created: 'file.ctime.format("YYYY-MM-DD")'
# 计算创建至今的天数(Duration 类型请结合 .days 使用)
days_old: '(now() - file.ctime).days'
# 计算距离截止日期还有几天
days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'
核心函数
以下为最常用的核心函数。关于所有类型(Date、String、Number、List、File、Link、Object、RegExp)的完整参考手册,请参阅 FUNCTIONS_REFERENCE.md。
| 函数 | 签名 | 描述 |
|---|---|---|
date() |
date(string): date |
将字符串解析为日期对象(YYYY-MM-DD HH:mm:ss) |
now() |
now(): date |
当前日期和时间 |
today() |
today(): date |
当前日期(时间部分为 00:00:00) |
if() |
if(condition, trueResult, falseResult?) |
条件分支判断 |
duration() |
duration(string): duration |
解析时间间隔字符串 |
file() |
file(path): file |
获取指定路径的文件对象 |
link() |
link(path, display?): Link |
创建内部链接 |
Duration(时间间隔)类型
两个日期相减时,返回的结果是 Duration 类型(而非普通数字)。
Duration 属性字段: duration.days、duration.hours、duration.minutes、duration.seconds、duration.milliseconds
重要说明: Duration 本身不支持直接调用 .round()、.floor()、.ceil()。必须先访问具体的数值字段(如 .days),然后再应用数值处理函数。
# 正确写法:计算两日期之间的天数
"(date(due_date) - today()).days" # 返回天数数值
"(now() - file.ctime).days" # 返回创建以来的天数
"(date(due_date) - today()).days.round(0)" # 取整后的天数
# 错误示范 - 会导致报错:
# "((date(due) - today()) / 86400000).round(0)" # Duration 不支持除法运算后接 round
日期计算
# Duration 时间单位:y/year/years, M/month/months, d/day/days,
# w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds
"now() + \"1 day\"" # 明天
"today() + \"7d\"" # 一周后
"now() - file.ctime" # 返回 Duration 类型
"(now() - file.ctime).days" # 以数值形式获取天数
视图类型
表格视图 (Table View)
views:
- type: table
name: "My Table"
order:
- file.name
- status
- due_date
summaries:
price: Sum
count: Average
卡片视图 (Cards View)
views:
- type: cards
name: "Gallery"
order:
- file.name
- cover_image
- description
列表视图 (List View)
views:
- type: list
name: "Simple List"
order:
- file.name
- status
地图视图 (Map View)
需要笔记中包含经纬度属性(latitude/longitude),并安装了 Maps 社区插件。
views:
- type: map
name: "Locations"
# 用于指定 lat/lng 属性的地图特定配置
默认汇总公式
| 名称 | 输入类型 | 描述 |
|---|---|---|
Average |
Number | 算术平均值 |
Min |
Number | 最小值 |
Max |
Number | 最大值 |
Sum |
Number | 所有数值求和 |
Range |
Number | 极差(最大值 - 最小值) |
Median |
Number | 中位数 |
Stddev |
Number | 标准差 |
Earliest |
Date | 最早日期 |
Latest |
Date | 最晚日期 |
Range |
Date | 日期跨度(最晚 - 最早) |
Checked |
Boolean | True 值的数量 |
Unchecked |
Boolean | False 值的数量 |
Empty |
Any | 空值数量 |
Filled |
Any | 非空值数量 |
Unique |
Any | 去重后的唯一值数量 |
完整示例
任务追踪 Base
filters:
and:
- file.hasTag("task")
- 'file.ext == "md"'
formulas:
days_until_due: 'if(due, (date(due) - today()).days, "")'
is_overdue: 'if(due, date(due) < today() && status != "done", false)'
priority_label: 'if(priority == 1, "🔴 High", if(priority == 2, "🟡 Medium", "🟢 Low"))'
properties:
status:
displayName: Status
formula.days_until_due:
displayName: "Days Until Due"
formula.priority_label:
displayName: Priority
views:
- type: table
name: "Active Tasks"
filters:
and:
- 'status != "done"'
order:
- file.name
- status
- formula.priority_label
- due
- formula.days_until_due
groupBy:
property: status
direction: ASC
summaries:
formula.days_until_due: Average
- type: table
name: "Completed"
filters:
and:
- 'status == "done"'
order:
- file.name
- completed_date
阅读清单 Base
filters:
or:
- file.hasTag("book")
- file.hasTag("article")
formulas:
reading_time: 'if(pages, (pages * 2).toString() + " min", "")'
status_icon: 'if(status == "reading", "📖", if(status == "done", "✅", "📚"))'
year_read: 'if(finished_date, date(finished_date).year, "")'
properties:
author:
displayName: Author
formula.status_icon:
displayName: ""
formula.reading_time:
displayName: "Est. Time"
views:
- type: cards
name: "Library"
order:
- cover
- file.name
- author
- formula.status_icon
filters:
not:
- 'status == "dropped"'
- type: table
name: "Reading List"
filters:
and:
- 'status == "to-read"'
order:
- file.name
- author
- pages
- formula.reading_time
每日笔记索引
filters:
and:
- file.inFolder("Daily Notes")
- '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'
formulas:
word_estimate: '(file.size / 5).round(0)'
day_of_week: 'date(file.basename).format("dddd")'
properties:
formula.day_of_week:
displayName: "Day"
formula.word_estimate:
displayName: "~Words"
views:
- type: table
name: "Recent Notes"
limit: 30
order:
- file.name
- formula.day_of_week
- formula.word_estimate
- file.mtime
嵌入 Bases
在 Markdown 文件中进行嵌入:
![[MyBase.base]]
<!-- 嵌入指定视图 -->
![[MyBase.base#View Name]]
YAML 引号使用规则
- 当公式中包含双引号时,外层请统一使用单引号包裹:
'if(done, "Yes", "No")' - 简单字符串使用双引号:
"My View Name" - 复杂表达式中嵌套引号需按规范正确转义
常见问题排查
YAML 语法错误
特殊字符未加引号:包含 :、{、}、[、]、,、&、*、#、?、|、-、<、>、=、!、%、@、` 的字符串必须使用引号包裹。
# 错误写法 - 未加引号的字符串中含有冒号
displayName: Status: Active
# 正确写法
displayName: "Status: Active"
公式内部引号未匹配:当公式内部包含双引号时,请用单引号包裹整个公式表达式。
# 错误示范 - 双引号内部直接嵌套双引号
formulas:
label: "if(done, "Yes", "No")"
# 正确写法 - 外层单引号包裹内层双引号
formulas:
label: 'if(done, "Yes", "No")'
常见公式错误
未访问具体字段就直接进行 Duration 运算:日期相减返回的是 Duration 类型而非数值。请务必先访问具体的字段(如 .days)。
<!-- truncated for translation batch; full body continues in source -->






