Obsidian插件 | Dataview:统计笔记数据
dataview 是 obsidian 上非常热门的插件,它可以通过类似 SQL 的语法,来查询所有笔记的统计数据,达成和 Notion 一样类似的 database 效果。还可以通过 js 代码调用 dataview 的 api 接口,来进一步处理统计到的数据,官方提供了非常详细的文档,参考官方文档就基本能完全使用 dataview 这个插件了。
介绍
数据索引
dataview 只会访问笔记里特定的数据,不会读取所有的内容。
- 标签
- 列表(任务)
- 通过字段添加的数据
- YAML Frontmatter
- 内联字段(Inline Fields):
[key::value]
语法
数据索引相当于是把每个笔记的对象键值对生成出来
数据查询
有三种方式写数据查询:
- Dataview Query Lanuage
- 行内查询语句
- 最灵活也是最复杂的,Javascript Query
Metadata
dataview 不能访问所有的笔记内容,为了搜索、过滤和显示内容,所有的笔记都要被建立索引。内置的字段会被自动编入索引,比如列表,其他的数据就要被保存进 metadata 字段来被 dataview 访问
Frontmatter
是 Markdown 扩展的一部分语法,可以在文章顶部添加 YAML 数据。
---
alias: "document"
last-reviewed: 2021-08-17
thoughts:
rating: 8
reviewable: false
---
可以使用以下语句来查询:
LIST
WHERE thoughts.rating = 8
提示
通过 Frontmatter 添加的字段是可以直接访问的,不用通过 file.frontmatter.xxx
来访问。
行内字段
如果想要更加自然的表达和标注,可以使用行内字段,通过 key::value
的方式。
感觉并不是很实用,省去介绍
内置字段
如果不想手动添加任何 metadata,dataview 也提供了很多已经被编入索引的字段。
- 文件的创建日:
file.cday
- 文件的链接:
file.outlinks
- 文件中包含的标签:
file.etags
- 文件中所有的 list:
file.lists
具体字段可以参考 Metadata on Pages
Dataview Query Language (DQL)
DQL 是类似 SQL 的语言,也是 dataview 的核心功能。它支持:
- 选择一种输出格式
- 选择从哪些数据源中获取数据(数据源指的就是文件夹、标签或者链接)
- 利用简单的比较或者其他操作过滤笔记或者数据
- 变换字段的展现形式,例如做一些计算
- 根据字段排序
- 根据字段聚类
- 限制输出的条数
结构
代码块后要加 dataview
<QUERY-TYPE> <fields>
FROM <source>
<DATA-COMMAND> <expression>
<DATA-COMMAND> <expression> ...
输出格式
- TABLE:查询结果的表格,输出一栏或多栏的字段数据
- LIST:查询结果的列表,输出每个页面的一个字段
- TASK:可以交互的任务列表
- CALENDAR:日历视图
数据源
FROM
命令只能有一个或者零个,使用数据源的集合,限制查询的页面范围。
//查询文件夹及其子文件夹下的所有页面
LIST
FROM "Books"
//查询文件夹及其子文件夹下的所有页面,排除某一个文件夹
LIST
FROM !"Books"
//查询包含标签的所有页面
LIST
FROM #status/open OR #status/wip
//查询链接特定页面的所有页面
LIST
FROM outgoing([[School Dashboard Current To Dos]])
过滤、排序、聚类和限制
除了 FROM
的其他数据命令都可以执行多次。
- WHERE: Filter notes based on information inside notes, the meta data fields. 根据笔记内信息过滤
- SORT: Sorts your results depending on a field and a direction. 根据字段排序查询结果
- GROUP BY: Bundles up several results into one result row per group. 把多个查询结果处理为每个 group 的一行结果
- LIMIT: Limits the result count of your query to the given number. 限制输出结果的行数
- FLATTEN: Splits up one result into multiple results based on a field or calculation. 将一行结果展平成多行
TASK
WHERE !completed
SORT created ASC
LIMIT 10
GROUP BY file.link
SORT rows.file.ctime ASC
函数
DQL 包含了一些函数帮助处理数据,例如时间的格式化 date
、查看字符串是否包含所需的字符 contains
。
具体函数查看DQL Functions
Dataview JS
注意
DQL 中的一些函数不支持在 Dataview JS 中使用。
代码块后要加 dataviewjs
dv.pages("#thing")...
Data Arrays
作为 Dataview JS 查询的输出结果,DataArray
是 JavaScript
列表的一个代理,在原有类型的基础上扩展了相应的功能。Data Arrays 支持索引和迭代操作,包含了很多数据操作方法(函数式编程),sort
, groupBy
, distinct
, where
。
大多数 Dataview JS 接口的返回值都是 Data Arrays,例如 dv.page()
。将普通的 JavaScript array 转换成 Dataview array 可以使用 dv.array(<array>)
,转换为普通的 array 可以用 DataArray#array()
。
Data Arrays 除了可以通过普通列表索引来调用,也可以将列表对象的字段自动映射成新的列表。比如 dv.pages().file.name
会返回文件名称的列表。
DataArray
的 api 接口:
length: number;
where(predicate: ArrayFunc<T, boolean>): DataArray<T>;
filter(predicate: ArrayFunc<T, boolean>): DataArray<T>;
sort<U>(key: ArrayFunc<T, U>, direction?: "asc" | "desc", comparator?: ArrayComparator<U>): DataArray<T>;
groupBy<U>(key: ArrayFunc<T, U>, comparator?: ArrayComparator<U>): DataArray<{ key: U; rows: DataArray<T> }>;
forEach(f: ArrayFunc<T, void>): void;
代码块
dataviewjs
的 api 可以通过 dv
或者 dataview
变量来调用。通过这个变量可以查询数据、展示 HTML 内容,配置视图。
查询
dv.current()
:脚本当前页面dv.pages(source)
:返回查询数据源下的页面 Data Array
展示
dv.el(element, text)
:根据给定的 HTML 元素展示内容dv.header(level, text)
:展示标题dv.paragraph(text)
:把内容展示在段落里dv.span(text)
:把内容展示在 span 里,没有上下的 padding,与段落不同
视图
dv.list(elements)
:展示列表dv.table(headers, elements)
:展示表格
dv.table(["File", "Genre", "Time Read", "Rating"], dv.pages("#book") .sort(b => b.rating) .map(b => [b.file.link, b.genre, b["time-read"], b.rating]))
工具函数
dv.date(text)
:把日期转换成 Luxon 库的DateTime 格式dv.duration(text)
:把时间转换成 Luxon 库格式的 Durationdv.compare(a, b)
:比较两个文本的字典序dv.equal(a, b)
:比较两个文本的字典序是否相等