跳至主要內容

Obsidian插件 | Dataview:统计笔记数据

Milton原创大约 6 分钟知识管理

dataview 是 obsidian 上非常热门的插件,它可以通过类似 SQL 的语法,来查询所有笔记的统计数据,达成和 Notion 一样类似的 database 效果。还可以通过 js 代码调用 dataview 的 api 接口,来进一步处理统计到的数据,官方提供了非常详细的文档open in new window,参考官方文档就基本能完全使用 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 Pagesopen in new window

Dataview Query Language (DQL)

DQL 是类似 SQL 的语言,也是 dataview 的核心功能。它支持:

  1. 选择一种输出格式
  2. 选择从哪些数据源中获取数据(数据源指的就是文件夹、标签或者链接)
  3. 利用简单的比较或者其他操作过滤笔记或者数据
  4. 变换字段的展现形式,例如做一些计算
  5. 根据字段排序
  6. 根据字段聚类
  7. 限制输出的条数

结构

代码块后要加 dataview

<QUERY-TYPE> <fields> 
FROM <source> 
<DATA-COMMAND> <expression> 
<DATA-COMMAND> <expression> ... 

输出格式

  1. TABLE:查询结果的表格,输出一栏或多栏的字段数据
  2. LIST:查询结果的列表,输出每个页面的一个字段
  3. TASK:可以交互的任务列表
  4. CALENDAR:日历视图

数据源

FROM 命令只能有一个或者零个,使用数据源的集合,限制查询的页面范围。

//查询文件夹及其子文件夹下的所有页面
LIST 
FROM "Books"

//查询文件夹及其子文件夹下的所有页面,排除某一个文件夹
LIST 
FROM !"Books"

//查询包含标签的所有页面
LIST 
FROM #status/open OR #status/wip

//查询链接特定页面的所有页面
LIST 
FROM outgoing([[School Dashboard Current To Dos]])

过滤、排序、聚类和限制

除了 FROM 的其他数据命令都可以执行多次。

  1. WHERE: Filter notes based on information inside notes, the meta data fields. 根据笔记内信息过滤
  2. SORT: Sorts your results depending on a field and a direction. 根据字段排序查询结果
  3. GROUP BY: Bundles up several results into one result row per group. 把多个查询结果处理为每个 group 的一行结果
  4. LIMIT: Limits the result count of your query to the given number. 限制输出结果的行数
  5. 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 Functionsopen in new window

Dataview JS

注意

DQL 中的一些函数不支持在 Dataview JS 中使用。

代码块后要加 dataviewjs

dv.pages("#thing")...

Data Arrays

作为 Dataview JS 查询的输出结果,DataArrayJavaScript 列表的一个代理,在原有类型的基础上扩展了相应的功能。Data Arrays 支持索引和迭代操作,包含了很多数据操作方法(函数式编程),sortgroupBydistinctwhere

大多数 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]))

工具函数

  1. dv.date(text) :把日期转换成 Luxon 库的DateTime 格式
  2. dv.duration(text) :把时间转换成 Luxon 库格式的 Duration
  3. dv.compare(a, b) :比较两个文本的字典序
  4. dv.equal(a, b) :比较两个文本的字典序是否相等

参考

  1. Dataview综合文档open in new window
  2. Dataview官网文档open in new window
  3. 给 Obsidian 来个起始页open in new window
  4. obsidian插件dataview官方文档翻译open in new window
  5. Obs131|Obsidian使用Dataviewjs動態查詢的嘗試open in new window
  6. Obsidian 插件:Dataviewopen in new window
  7. Obsidian 使用 Dataview 插件统计数据open in new window
  8. Dataview翻译 by 寡人open in new window
  9. Dataviewjs 基本用法open in new window