Obsidian学习笔记数据库技能
🎯 设计理念
为学习笔记优化的数据库系统,实现:
-
智能分类: 按学科、难度、状态自动分组
-
进度追踪: 实时监控学习进度和掌握情况
-
知识关联: 发现笔记间的关联关系
-
统计分析: 可视化学习数据和趋势
📊 核心功能
Obsidian Bases = YAML配置 + 动态查询 + 多视图展示
-
数据源: 笔记属性和元数据
-
查询引擎: 强大的过滤和公式系统
-
视图系统: 表格、卡片、列表等多种展示
-
统计分析: 自动计算和汇总功能
File Format
Base files use the .base extension and contain valid YAML. They can also be embedded in Markdown code blocks.
Complete Schema
Global filters apply to ALL views in the base
filters:
Can be a single filter string
OR a recursive filter object with and/or/not
and: [] or: [] not: []
Define formula properties that can be used across all views
formulas: formula_name: 'expression'
Configure display names and settings for properties
properties: property_name: displayName: "Display Name" formula.formula_name: displayName: "Formula Display Name" file.ext: displayName: "Extension"
Define custom summary formulas
summaries: custom_summary_name: 'values.mean().round(3)'
Define one or more views
views:
- type: table | cards | list | map
name: "View Name"
limit: 10 # Optional: limit results
groupBy: # Optional: group results
property: property_name
direction: ASC | DESC
filters: # View-specific filters
and: []
order: # Properties to display in order
- file.name
- property_name
- formula.formula_name summaries: # Map properties to summary formulas property_name: Average
Filter Syntax
Filters narrow down results. They can be applied globally or per-view.
Filter Structure
Single filter
filters: 'status == "done"'
AND - all conditions must be true
filters: and: - 'status == "done"' - 'priority > 3'
OR - any condition can be true
filters: or: - 'file.hasTag("book")' - 'file.hasTag("article")'
NOT - exclude matching items
filters: not: - 'file.hasTag("archived")'
Nested filters
filters: or: - file.hasTag("tag") - and: - file.hasTag("book") - file.hasLink("Textbook") - not: - file.hasTag("book") - file.inFolder("Required Reading")
Filter Operators
Operator Description
==
equals
!=
not equal
greater than
<
less than
=
greater than or equal
<=
less than or equal
&&
logical and
||
logical or
! logical not
Properties
Three Types of Properties
-
Note properties - From frontmatter: note.author or just author
-
File properties - File metadata: file.name , file.mtime , etc.
-
Formula properties - Computed values: formula.my_formula
File Properties Reference
Property Type Description
file.name
String File name
file.basename
String File name without extension
file.path
String Full path to file
file.folder
String Parent folder path
file.ext
String File extension
file.size
Number File size in bytes
file.ctime
Date Created time
file.mtime
Date Modified time
file.tags
List All tags in file
file.links
List Internal links in file
file.backlinks
List Files linking to this file
file.embeds
List Embeds in the note
file.properties
Object All frontmatter properties
The this Keyword
-
In main content area: refers to the base file itself
-
When embedded: refers to the embedding file
-
In sidebar: refers to the active file in main content
Formula Syntax
Formulas compute values from properties. Defined in the formulas section.
formulas:
Simple arithmetic
total: "price * quantity"
Conditional logic
status_icon: 'if(done, "✅", "⏳")'
String formatting
formatted_price: 'if(price, price.toFixed(2) + " dollars")'
Date formatting
created: 'file.ctime.format("YYYY-MM-DD")'
Complex expressions
days_old: '((now() - file.ctime) / 86400000).round(0)'
Functions Reference
Global Functions
Function Signature Description
date()
date(string): date
Parse string to date. Format: YYYY-MM-DD HH:mm:ss
duration()
duration(string): duration
Parse duration string
now()
now(): date
Current date and time
today()
today(): date
Current date (time = 00:00:00)
if()
if(condition, trueResult, falseResult?)
Conditional
min()
min(n1, n2, ...): number
Smallest number
max()
max(n1, n2, ...): number
Largest number
number()
number(any): number
Convert to number
link()
link(path, display?): Link
Create a link
list()
list(element): List
Wrap in list if not already
file()
file(path): file
Get file object
image()
image(path): image
Create image for rendering
icon()
icon(name): icon
Lucide icon by name
html()
html(string): html
Render as HTML
escapeHTML()
escapeHTML(string): string
Escape HTML characters
Any Type Functions
Function Signature Description
isTruthy()
any.isTruthy(): boolean
Coerce to boolean
isType()
any.isType(type): boolean
Check type
toString()
any.toString(): string
Convert to string
Date Functions & Fields
Fields: date.year , date.month , date.day , date.hour , date.minute , date.second , date.millisecond
Function Signature Description
date()
date.date(): date
Remove time portion
format()
date.format(string): string
Format with Moment.js pattern
time()
date.time(): string
Get time as string
relative()
date.relative(): string
Human-readable relative time
isEmpty()
date.isEmpty(): boolean
Always false for dates
Date Arithmetic
Duration units: y/year/years, M/month/months, d/day/days,
w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds
Add/subtract durations
"date + "1M"" # Add 1 month "date - "2h"" # Subtract 2 hours "now() + "1 day"" # Tomorrow "today() + "7d"" # A week from today
Subtract dates for millisecond difference
"now() - file.ctime"
Complex duration arithmetic
"now() + (duration('1d') * 2)"
String Functions
Field: string.length
Function Signature Description
contains()
string.contains(value): boolean
Check substring
containsAll()
string.containsAll(...values): boolean
All substrings present
containsAny()
string.containsAny(...values): boolean
Any substring present
startsWith()
string.startsWith(query): boolean
Starts with query
endsWith()
string.endsWith(query): boolean
Ends with query
isEmpty()
string.isEmpty(): boolean
Empty or not present
lower()
string.lower(): string
To lowercase
title()
string.title(): string
To Title Case
trim()
string.trim(): string
Remove whitespace
replace()
string.replace(pattern, replacement): string
Replace pattern
repeat()
string.repeat(count): string
Repeat string
reverse()
string.reverse(): string
Reverse string
slice()
string.slice(start, end?): string
Substring
split()
string.split(separator, n?): list
Split to list
Number Functions
Function Signature Description
abs()
number.abs(): number
Absolute value
ceil()
number.ceil(): number
Round up
floor()
number.floor(): number
Round down
round()
number.round(digits?): number
Round to digits
toFixed()
number.toFixed(precision): string
Fixed-point notation
isEmpty()
number.isEmpty(): boolean
Not present
List Functions
Field: list.length
Function Signature Description
contains()
list.contains(value): boolean
Element exists
containsAll()
list.containsAll(...values): boolean
All elements exist
containsAny()
list.containsAny(...values): boolean
Any element exists
filter()
list.filter(expression): list
Filter by condition (uses value , index )
map()
list.map(expression): list
Transform elements (uses value , index )
reduce()
list.reduce(expression, initial): any
Reduce to single value (uses value , index , acc )
flat()
list.flat(): list
Flatten nested lists
join()
list.join(separator): string
Join to string
reverse()
list.reverse(): list
Reverse order
slice()
list.slice(start, end?): list
Sublist
sort()
list.sort(): list
Sort ascending
unique()
list.unique(): list
Remove duplicates
isEmpty()
list.isEmpty(): boolean
No elements
File Functions
Function Signature Description
asLink()
file.asLink(display?): Link
Convert to link
hasLink()
file.hasLink(otherFile): boolean
Has link to file
hasTag()
file.hasTag(...tags): boolean
Has any of the tags
hasProperty()
file.hasProperty(name): boolean
Has property
inFolder()
file.inFolder(folder): boolean
In folder or subfolder
Link Functions
Function Signature Description
asFile()
link.asFile(): file
Get file object
linksTo()
link.linksTo(file): boolean
Links to file
Object Functions
Function Signature Description
isEmpty()
object.isEmpty(): boolean
No properties
keys()
object.keys(): list
List of keys
values()
object.values(): list
List of values
Regular Expression Functions
Function Signature Description
matches()
regexp.matches(string): boolean
Test if matches
View Types
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
Requires latitude/longitude properties and the Maps community plugin.
views:
- type: map
name: "Locations"
Map-specific settings for lat/lng properties
Default Summary Formulas
Name Input Type Description
Average
Number Mathematical mean
Min
Number Smallest number
Max
Number Largest number
Sum
Number Sum of all numbers
Range
Number Max - Min
Median
Number Mathematical median
Stddev
Number Standard deviation
Earliest
Date Earliest date
Latest
Date Latest date
Range
Date Latest - Earliest
Checked
Boolean Count of true values
Unchecked
Boolean Count of false values
Empty
Any Count of empty values
Filled
Any Count of non-empty values
Unique
Any Count of unique values
🎓 学习笔记数据库示例
学习进度总览
filters: and: - file.hasTag("学习") - 'file.ext == "md"'
formulas:
学习进度计算
progress_percent: 'if(progress, progress, 0)' mastery_level: 'if(confidence, "⭐".repeat(confidence), "📝")' urgency_score: 'if(priority == "高", 3, if(priority == "中", 2, 1))' days_since_created: '((now() - date(created)) / 86400000).round(0)' needs_review: 'if(next_review && date(next_review) < today(), "🔄", "")'
智能分类
category_type: 'if(file.hasTag("概念"), "📖 概念", if(file.hasTag("算法"), "⚙️ 算法", if(file.hasTag("实现"), "💻 实现", "📚 其他")))'
难度可视化
difficulty_emoji: 'if(difficulty == "入门", "🟢", if(difficulty == "进阶", "🟡", if(difficulty == "高级", "🔴", "⚪")))'
properties: status: displayName: "状态" difficulty: displayName: "难度" rating: displayName: "评分" formula.progress_percent: displayName: "进度%" formula.mastery_level: displayName: "掌握度" formula.category_type: displayName: "分类" formula.difficulty_emoji: displayName: "" formula.needs_review: displayName: ""
views:
-
type: table name: "📊 学习总览" order:
- formula.category_type
- file.name
- status
- formula.difficulty_emoji
- formula.progress_percent
- formula.mastery_level
- rating
- formula.needs_review groupBy: property: status direction: ASC summaries: formula.progress_percent: Average rating: Average
-
type: cards name: "🎯 当前学习" filters: and: - 'status == "学习中"' order:
- file.name
- formula.category_type
- formula.difficulty_emoji
- formula.progress_percent
- formula.mastery_level
📚 知识体系管理
filters: and: - or: - file.hasTag("概念") - file.hasTag("算法") - file.hasTag("理论")
formulas:
知识关联度
link_count: 'file.links.length' backlink_count: 'file.backlinks.length' knowledge_score: '(rating * confidence + link_count + backlink_count) / 3'
学习路径
learning_stage: 'if(progress < 30, "🌱 初学", if(progress < 70, "🌿 进阶", "🌳 精通"))' completion_rate: 'if(progress, progress, 0)'
依赖关系
has_prerequisites: 'if(prerequisites, "✅", "❌")' dependency_count: 'if(dependencies, dependencies.length, 0)'
时间分析
learning_duration: '((date(modified) - date(created)) / 86400000).round(0)' is_recent: 'if(date(modified) > now() - "7d", "🆕", "")'
properties: formula.learning_stage: displayName: "学习阶段" formula.knowledge_score: displayName: "知识分" formula.link_count: displayName: "链接数" formula.completion_rate: displayName: "完成度" formula.has_prerequisites: displayName: "前置" formula.learning_duration: displayName: "学习天数" formula.is_recent: displayName: ""
views:
-
type: table name: "🧠 知识图谱" order:
- file.name
- formula.learning_stage
- formula.knowledge_score
- formula.link_count
- formula.backlink_count
- formula.completion_rate
- formula.has_prerequisites
- formula.learning_duration
- formula.is_recent groupBy: property: difficulty direction: ASC summaries: formula.knowledge_score: Average formula.completion_rate: Average
-
type: list name: "🎯 核心概念" filters: and: - file.hasTag("概念") - 'rating >= 4' order:
- file.name
- formula.knowledge_score
- confidence
📈 学习统计分析
filters: and: - file.hasTag("学习") - 'progress != ""'
formulas:
统计指标
total_notes: '1' completed_count: 'if(status == "已掌握", 1, 0)' in_progress_count: 'if(status == "学习中", 1, 0)'
质量评估
quality_score: '(rating + confidence + progress) / 3' is_high_quality: 'if(quality_score >= 4, "🏆", "")'
效率分析
efficiency: 'if(learning_duration > 0, (progress / learning_duration).round(2), 0)' is_efficient: 'if(efficiency >= 5, "⚡", "")'
复习管理
review_overdue: 'if(next_review && date(next_review) < today(), "⏰", "")' days_to_review: 'if(next_review, ((date(next_review) - today()) / 86400000).round(0), "")'
summaries: total_learning: 'values.sum()' completion_rate: '(values.filter(v => v == 1).sum() / values.sum() * 100).round(1)' avg_quality: 'values.mean().round(2)' avg_efficiency: 'values.mean().round(2)'
properties: formula.quality_score: displayName: "质量分" formula.efficiency: displayName: "效率" formula.is_high_quality: displayName: "" formula.is_efficient: displayName: "" formula.review_overdue: displayName: "复习" formula.days_to_review: displayName: "天数"
views:
-
type: table name: "📊 学习统计" order:
- file.name
- status
- formula.quality_score
- formula.efficiency
- progress
- formula.review_overdue
- formula.days_to_review
- formula.is_high_quality
- formula.is_efficient summaries: formula.total_notes: total_learning formula.completed_count: completion_rate formula.quality_score: avg_quality formula.efficiency: avg_efficiency
-
type: table name: "⏰ 复习提醒" filters: or: - 'next_review && date(next_review) <= today() + "3d"' - 'next_review == ""' order:
- formula.days_to_review
- file.name
- status
- confidence
- formula.review_overdue
Daily Notes Index
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
Embedding Bases
Embed in Markdown files:
![[MyBase.base]]
<!-- Specific view --> ![[MyBase.base#View Name]]
YAML Quoting Rules
-
Use single quotes for formulas containing double quotes: 'if(done, "Yes", "No")'
-
Use double quotes for simple strings: "My View Name"
-
Escape nested quotes properly in complex expressions
Common Patterns
Filter by Tag
filters: and: - file.hasTag("project")
Filter by Folder
filters: and: - file.inFolder("Notes")
Filter by Date Range
filters: and: - 'file.mtime > now() - "7d"'
Filter by Property Value
filters: and: - 'status == "active"' - 'priority >= 3'
Combine Multiple Conditions
filters: or: - and: - file.hasTag("important") - 'status != "done"' - and: - 'priority == 1' - 'due != ""'
References
-
Bases Syntax
-
Functions
-
Views
-
Formulas