Obsidian Dataview 函数实战指南:从入门到精通的数据处理技巧
【免费下载链接】obsidian-dataviewA high-performance data index and query language over Markdown files, for https://obsidian.md/.项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-dataview
为什么需要掌握这些函数?
想象一下,你有一个装满笔记的数字图书馆,里面有几百篇读书笔记、几十个人物档案和上百条待办任务。当你想找出"去年读过的所有科幻小说"或者"优先级最高的工作任务"时,难道要一篇篇手动查找吗?这就是Dataview函数的价值所在——它们就像你私人的数据管家,能帮你从海量笔记中快速筛选、整理和分析信息。
掌握这些函数不仅能节省你的时间,更能让你发现笔记之间隐藏的关联。比如通过filter和map的组合,你可以自动生成项目进度报告;使用date和dur函数,能轻松追踪阅读习惯。函数是Dataview的灵魂,也是从"简单查询"迈向"数据洞察"的关键一步。
第一阶段:基础操作 - 数据世界的ABC
学习目标🎯
- 掌握5种核心数据类型的创建方法
- 熟练进行基本类型转换
- 理解函数向量化特性的实际应用
数据类型构造函数
list(value1, value2, ...)/array(...)
功能描述:创建一个包含多个值的列表,就像购物清单一样把相关数据打包在一起。
使用场景:当你需要处理一组相关数据时,比如一本书的多个作者、一个项目的所有任务标签等。
避坑指南:列表中的元素可以是不同类型(数字、字符串、日期等),但尽量保持类型一致以便后续处理。
实用案例:创建包含多本书名的阅读列表
list("1984", "美丽新世界", "我们") // 创建反乌托邦小说列表object(key1, value1, ...)
功能描述:创建键值对形式的对象,类似于通讯录中"姓名-电话"的对应关系。
使用场景:存储具有多个属性的实体,如一本书的元数据(标题、作者、评分)。
避坑指南:键名必须是字符串,且键值对必须交替出现,数量为偶数。
实用案例:创建书籍信息对象
object("title", "三体", "author", "刘慈欣", "rating", 9.5)date(any)
功能描述:解析各种格式的输入为日期对象,相当于给混乱的时间信息贴上整齐的标签。
使用场景:处理笔记中的创建日期、阅读完成日期、任务截止日期等时间相关数据。
避坑指南:日期字符串尽量使用"YYYY-MM-DD"格式以确保解析准确性。
实用案例:计算距今的天数
date(today) - date("2023-01-01") // 计算今年已过去的天数dur(any)
功能描述:解析文字描述的时间长度为持续时间对象,就像把"一杯咖啡的时间"转化为具体的分钟数。
使用场景:记录阅读时长、项目耗时、会议长度等时间间隔数据。
避坑指南:支持的单位包括秒(s)、分(m)、时(h)、天(d)、周(w),混合单位需用逗号分隔。
实用案例:计算平均阅读速度
dur("3h20m") / 350 // 3小时20分钟读完350页,计算每页所需时间number(string)
功能描述:从文本中提取数字,就像从信封上撕下邮票一样提取有用的数值信息。
使用场景:处理包含数字的文本字段,如"价格:$29.99"中提取29.99。
避坑指南:只会提取第一个连续数字,忽略后续内容。
实用案例:从评分文本中提取数值
number("评分:4.5/5") // 提取4.5类型转换函数
string(any)
功能描述:将任何数据类型转换为字符串,就像给不同类型的物品都套上统一的标签。
使用场景:需要文本形式展示数据时,如在表格中显示日期或数字。
避坑指南:对象转换会得到"[object Object]",建议先用extract提取所需字段。
实用案例:创建带格式的书名标签
string("《" + file.name + "》") // 将文件名转换为"《书名》"格式link(path, [display])
功能描述:创建Obsidian内部链接,相当于在笔记之间架起桥梁。
使用场景:在查询结果中创建可点击的文件链接,方便快速跳转。
避坑指南:路径可以是文件名(自动搜索)或相对路径,建议使用唯一的文件名。
实用案例:创建带别名的书籍链接
link(file.path, "📚 " + file.name) // 创建显示为"📚 书名"的链接实战场景💡:个人阅读记录管理
假设你有一个读书库,每本书都有"阅读日期"、"评分"和"类别"等元数据。现在需要创建一个基础的阅读记录查询:
TABLE link(file.path) AS "书名", string(date(reading_date)) AS "阅读日期", rating AS "评分", category AS "类别" FROM #book SORT reading_date DESC这个查询使用了link创建可点击书名,date解析阅读日期,string确保日期正确显示。结果会像这样:
自测题
- 如何创建一个包含3个待办任务的列表?
- 如何将"2小时30分钟"的阅读时间转换为持续时间对象?
- 如何从"完成于2023-05-15"这样的文本中提取日期?
第二阶段:数据处理 - 让信息为你工作
学习目标🎯
- 掌握数组过滤和转换的核心技巧
- 学会使用统计函数分析数据
- 熟练进行字符串模式匹配和处理
数组操作函数
filter(array, predicate)
功能描述:根据条件筛选数组元素,就像在一堆水果中挑出所有苹果。
使用场景:从大量数据中筛选符合特定条件的项目,如"评分高于9分的书籍"。
避坑指南: predicate函数应返回布尔值,true保留元素,false排除元素。
实用案例:筛选高评分科幻小说
filter(rows, (row) => row.category = "科幻" and row.rating >= 9)map(array, func)
功能描述:对数组中的每个元素应用函数,就像工厂流水线对每个产品进行相同加工。
使用场景:批量转换数据,如统一调整评分格式、提取标题关键词等。
避坑指南:函数应返回新值,原数组不会被修改,而是返回新数组。
实用案例:为所有书名添加类别前缀
map(rows, (row) => row.category + " - " + row.title)sort(array, [func])
功能描述:对数组进行排序,就像整理扑克牌一样按特定顺序排列。
使用场景:任何需要有序展示的数据,如按日期排序的日记、按评分排序的电影列表。
避坑指南:默认按升序排列,数字按大小,字符串按字母顺序,日期按时间先后。
实用案例:按阅读日期倒序排列书籍
sort(rows, (a, b) => b.reading_date - a.reading_date)统计函数
sum(array)/average(array)
功能描述:计算数组的总和/平均值,就像自动计算器帮你统计数据。
使用场景:分析数值数据,如计算平均评分、总阅读时长等。
避坑指南:数组元素必须是数字,非数字值会被视为0。
实用案例:计算科幻类书籍的平均评分
average(filter(rows, (r) => r.category = "科幻").rating)minby(array, func)/maxby(array, func)
功能描述:根据指定函数计算结果找出最小/最大值对应的元素,就像在马拉松比赛中找到最快和最慢的选手。
使用场景:找出极端值对应的完整记录,如"评分最高的书"、"耗时最长的项目"。
避坑指南:func参数应返回可比较的值(通常是数字或日期)。
实用案例:找出阅读时间最长的书
maxby(rows, (r) => dur(r.read_time).minutes)字符串操作函数
regextest(pattern, string)
功能描述:检查字符串是否包含匹配正则模式的内容,就像安检仪检查行李中是否有特定物品。
使用场景:复杂的文本匹配,如识别包含特定关键词的笔记、验证格式是否正确等。
避坑指南:正则表达式语法较为特殊,需注意转义特殊字符(如.、*等)。
实用案例:查找标题包含年份的书籍
regextest("\d{4}", row.title) // 匹配包含4位数字的标题replace(string, pattern, replacement)
功能描述:替换字符串中的特定内容,就像用涂改液修改错别字。
使用场景:标准化数据格式,如统一日期显示、替换特殊字符等。
实用案例:清理标题中的特殊符号
replace(row.title, "[\*\:\"\<\>\|\?\/]", "") // 移除标题中的特殊字符实战场景💡:电影收藏管理系统
假设你有一个电影收藏库,包含电影名称、类型、评分、观看日期等信息。现在需要创建一个高级查询,按类型分组显示,并计算每个类型的平均评分:
TABLE WITHOUT ID category AS "类型", length(rows) AS "数量", round(average(rows.rating), 1) AS "平均评分", sort(rows, (a,b) => b.rating)[0].title AS "最高分电影" FROM #movie GROUP BY category SORT length(rows) DESC这个查询使用了length计算数量,average和round计算平均评分,sort和数组索引找出最高分电影。结果会类似这样:
自测题
- 如何筛选出所有"未完成"且"优先级高"的任务?
- 如何将一组价格字符串(如"$19.99")转换为数字并计算总和?
- 如何找出创建日期最早的10篇笔记?
第三阶段:高级应用 - 函数组合的艺术
学习目标🎯
- 掌握多函数组合使用的技巧
- 学会构建复杂数据处理流水线
- 能够解决实际工作中的复杂数据问题
函数组合示例
组合1:任务完成情况分析
需求:统计每周完成的任务数量,并计算完成率
实现代码:
TABLE dateformat(week, "yyyy-'W'ww") AS "周", length(rows) AS "总任务数", length(filter(rows, (r) => r.completed)) AS "已完成", round(length(filter(rows, (r) => r.completed)) / length(rows) * 100, 0) AS "完成率(%)" FROM #task WHERE completed GROUP BY dateformat(file.ctime, "yyyy-ww") AS week SORT week DESC函数组合解析:
dateformat:将创建时间转换为周格式filter:筛选已完成任务length:计算任务数量round:格式化百分比显示
组合2:读书笔记质量分析
需求:分析不同类别书籍的笔记长度与评分的关系
实现代码:
TABLE category AS "类别", round(average(rows.word_count), 0) AS "平均字数", round(average(rows.rating), 1) AS "平均评分", cor(rows.word_count, rows.rating) AS "相关性" FROM #book_note GROUP BY category WHERE word_count > 0函数组合解析:
average:计算平均字数和评分cor:计算字数与评分的相关系数WHERE:过滤掉字数为0的无效笔记
组合3:项目进度追踪
需求:展示各项目的任务完成情况,包括进度条可视化
实现代码:
TABLE project AS "项目", length(rows) AS "总任务", length(filter(rows, (r) => r.status = "完成")) AS "已完成", "[" + repeat("■", round(length(filter(rows, (r) => r.status = "完成")) / length(rows) * 10) ) + repeat("□", 10 - round(length(filter(rows, (r) => r.status = "完成")) / length(rows) * 10) ) + "]" AS "进度" FROM #task GROUP BY project SORT project ASC函数组合解析:
filter:筛选不同状态的任务round:计算进度百分比repeat:创建进度条可视化+:字符串拼接
跨函数综合应用场景
场景1:个人知识管理仪表盘
需求:创建一个仪表盘,展示笔记数量、分类分布、最近创建的笔记等信息。
实现方案:
TABLE WITHOUT ID "📚 总笔记数" AS "指标", length(rows) AS "数值" FROM "" WHERE file.name != this.file.name UNION TABLE WITHOUT ID "📊 分类分布" AS "指标", category + ": " + string(length(rows)) AS "数值" FROM "" WHERE file.name != this.file.name AND category GROUP BY category UNION TABLE WITHOUT ID "🕒 最近创建" AS "指标", link(file.path) AS "数值" FROM "" WHERE file.name != this.file.name SORT file.ctime DESC LIMIT 5关键函数组合:length统计总数,GROUP BY分类汇总,SORT和LIMIT获取最近笔记,link创建可点击链接。
场景2:阅读习惯分析系统
需求:分析阅读量随时间的变化、不同类型书籍的阅读占比、以及阅读速度的变化趋势。
实现方案:
CHART SUM(length) AS "月度阅读页数" FROM #book GROUP BY dateformat(reading_date, "yyyy-MM") AS month SORT month ASC TABLE category AS "书籍类型", sum(length) AS "总页数", round(sum(length) / total_pages * 100, 0) AS "占比(%)", round(average(length / dur(read_time).hours), 1) AS "阅读速度(页/小时)" FLATTEN sum(length) AS total_pages FROM #book GROUP BY category关键函数组合:sum计算总页数,dur解析阅读时间,dateformat按月份分组,average计算平均阅读速度。
场景3:智能任务管理系统
需求:根据截止日期、优先级和依赖关系,自动排序任务并突出显示紧急任务。
实现方案:
TASK FROM #task WHERE !completed SORT date(due) - date(today) ASC, // 按截止日期排序 priority DESC, // 按优先级排序 length(depends) ASC // 按依赖数量排序 WHERE date(due) - date(today) <= 7 OR // 7天内到期 priority = "high" // 高优先级关键函数组合:date计算日期差,length评估依赖复杂度,多条件SORT实现智能排序,复合WHERE筛选紧急任务。
实战场景💡:个人年度回顾系统
创建一个自动化的年度回顾页面,综合分析你的笔记、任务和阅读数据:
# 年度回顾 2023 ## 写作统计 - 总笔记数: `=length(filter(file.inlinks, (l) => startswith(l.path, "2023/")))` - 总字数: `=sum(filter(file.inlinks, (l) => startswith(l.path, "2023/")).word_count)` - 平均每篇字数: `=round(sum(filter(file.inlinks, (l) => startswith(l.path, "2023/")).word_count) / length(filter(file.inlinks, (l) => startswith(l.path, "2023/"))), 0)` ## 阅读统计 ```dataview TABLE "📚 " + category AS "类别", length(rows) AS "本数", sum(length) AS "总页数", round(average(rating), 1) AS "平均评分" FROM #book WHERE reading_date >= date("2023-01-01") AND reading_date <= date("2023-12-31") GROUP BY category SORT length(rows) DESC任务完成情况
CHART length(rows) AS "完成任务数" FROM #task WHERE completed AND date(completed_date) >= date("2023-01-01") GROUP BY dateformat(date(completed_date), "MMM") AS month SORT month ASC这个综合系统使用了多种函数组合,从不同维度分析一年的数据,生成全面的个人年度回顾。 ### 自测题 1. 如何结合`filter`、`map`和`sum`计算所有"编程"类笔记的总字数? 2. 如何使用函数组合创建一个按周显示的阅读进度日历? 3. 如何构建一个任务优先级自动分类系统,综合考虑截止日期、重要性和预计耗时? ## 学习路径图 ### 入门阶段(1-2周) 1. 熟悉基础构造函数:`list`、`object`、`date` 2. 掌握简单类型转换:`string`、`number`、`link` 3. 练习基本查询中的函数应用 ### 进阶阶段(2-4周) 1. 学习数组操作:`filter`、`map`、`sort` 2. 掌握统计函数:`sum`、`average`、`minby`/`maxby` 3. 练习字符串处理:`regextest`、`replace`、`lower`/`upper` ### 精通阶段(1-2个月) 1. 学习多函数组合技巧 2. 掌握复杂查询和数据可视化 3. 构建个人化数据应用系统 ## 常见问题诊断 ### 问题1:函数返回"null"或"undefined" **可能原因**: - 输入数据为空或不存在 - 函数参数类型不匹配 - 路径或文件名错误 **解决方法**: - 使用`nonnull`过滤空值:`nonnull(array)` - 检查数据类型:`typeof(value)` - 使用`contains`验证存在性:`contains(object, "key")` ### 问题2:日期计算结果不正确 **可能原因**: - 日期格式解析错误 - 时区设置问题 - 日期对象与字符串混淆 **解决方法**: - 统一使用"YYYY-MM-DD"格式 - 使用`dateformat`明确指定格式 - 确认操作对象是日期类型:`typeof(date) = "date"` ### 问题3:列表处理性能低下 **可能原因**: - 处理的数据集过大 - 嵌套函数调用过于复杂 - 频繁使用`filter`和`map`的组合 **解决方法**: - 先筛选再处理:`map(filter(array, cond), func)`而非`filter(map(array, func), cond)` - 使用`limit`减少数据量 - 分解复杂操作,分步处理 ### 问题4:正则表达式不匹配 **可能原因**: - 特殊字符未转义 - 正则语法错误 - 大小写敏感问题 **解决方法**: - 使用`icontains`进行不区分大小写的简单匹配 - 转义特殊字符:`\.`匹配点,`\*`匹配星号 - 使用在线正则测试工具验证表达式 通过系统学习和实践这些函数,你将能够把Obsidian从简单的笔记工具转变为强大的个人数据管理中心。记住,最好的学习方法是边用边学——选择一个实际问题,尝试用函数组合来解决它。随着实践的深入,这些函数将成为你的第二本能,让你轻松驾驭任何数据处理挑战。【免费下载链接】obsidian-dataviewA high-performance data index and query language over Markdown files, for https://obsidian.md/.项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-dataview
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考