Obsidian Dataview

113次阅读
没有评论

共计 6597 个字符,预计需要花费 17 分钟才能阅读完成。

本文是Obsidian 漫游指南系列中的第 8/15 篇文章

如果说 Obsidian 有高中低等几种级别的玩法,那么 Dataview 必然会是高级玩法中的必备组件之一。Dataview 为 Obsidian 带来了动态查询数据和展示的能力,比如官方列的一些应用场景:

这是一个简单但强大的想法:

  • 在每日笔记中记录睡眠时间表和习惯来跟踪它们,并自动创建睡眠时间表的每周报表。
  • 自动收集笔记中书籍的链接,并按评分对它们排序。
  • 自动收集带有指定日期注释的页面,将它们显示在每日笔记或其他地方中。
  • 查看没有后续标记的页面,或显示特定标记的页面。
  • 创建即将到来的事件的动态视图,并附注注释。

注:本文示例文档见 obsidian-roam-guide

组件

Dataview 主要由 annotation 和 querying 两大组件构成。下面说下这两类组件的用法。

Annotation

Annotation 用来标注字段信息,经过查询后展示字段值,目前 Annotation 有三类设置方式。

Front Matter

除了 Obsidian 默认的几个 Key 外,Dataview 支持在 Front Matter 自定义 Annotation 来设置 Key,如下:

---
name: Obsidian 漫游指南
url: https://qileq.com/series/obsidian/
priority: High
status: In Progressing
---

该方式设置的 Annotation 在阅读模式不可见。

行内字段

若要在文件内容中设置 Annotation,可使用如下三种方式:

  1. Key:: Value:单独一行设置 Annotation,该方式在阅读模式原样展示。
  2. [Key:: Value]:如果要插入在一行中则使用本方式,该方式在阅读模式中仅显示 Key 和 Value。
  3. (Key:: Value):和 [Key:: Value] 类似,但在阅读模式中仅显示 Value。

隐式字段

Dataview 默认在每个页面、任务和列表中都添加了如下 Annotation 元信息,如下:

页面 Annotation 元信息

页面 Annotation 元信息如下:

  • file.name: 文件名
  • file.folder: 文件所属的文件夹
  • file.path: 文件路径
  • file.ext: 文件扩展属性,如为 .md
  • file.link: 文件链接
  • file.size: 文件大小
  • file.ctime: 文件创建时间(日期 + 时间)
  • file.cday: 文件创建日期(日期)
  • file.mtime: 文件最后修改时间(日期 + 时间)
  • file.mday: 文件最后修改日期(日期)
  • file.tags: 文件 tags,多级 tags 会被分开存储,如 #Tag/1/A 会被存储为 [#Tag, #Tag/1, #Tag/1/A]
  • file.etags: 文件显式指定的 tags,不会像 file.tags 一样拆分 tags
  • file.inlinks: 所有引用该文件的文件(即入链)
  • file.outlinks: 该文件引用的所有文件(即出链)
  • file.aliases: 文件 aliases 数组
  • file.tasks: 文件中所有的任务列表(任务形式为 - [ ]- [x]
  • file.lists: 文件中的所有列表(包括任务列表)
  • file.frontmatter: Front Matter 中所有信息,主要用于检查原始 Front Matter 或动态展示 Front Matter 值
  • file.day: 如果文件名中有形如 yyyy-mm-ddyyyymmdd 的日期信息,可通过本字段获取
  • file.starred: 文件是否标星(若是会在 Starred Files 中显示)
任务 Annotation 元信息

任务 Annotation 元信息如下:

  • status: 任务状态,任务由 标记,默认为空,表示未完成;即 表示任务未完成,若为 [X] 表示任务已完成
  • checked: 任务是否已被检查(如状态是否完成)
  • completed: 标记任务是否已完成,若状态为 X 则为完成,不考虑该任务下子任务的状态
  • fullyCompleted: 是否所有子任务均已完成
  • text: 任务文本
  • line: 任务显示行
  • lineCount: 任务行数
  • path: 任务路径
  • section: 任务所属块
  • tags: 任务中的 tags
  • outlinks: 任务中定义的链接
  • link: 离此任务最近的链接
  • children: 任务的子任务列表
  • task: 若为 true 则表示为任务,否则表示常规列表
  • completion: 任务完成时间,可通过 [completion:: ...]Completed Date: ✅YYYYY-MM-DD(如 Completed last saturday ✅2022-12-21 )设置
  • due: 任务截至日期,可通过 [due:: ...]Due Date: 🗓️YYYY-MM-DD(如 Due this saturday 🗓️2021-08-29)设置
  • created: 任务创建日期,可通过 [created:: ...]Created Date: ➕YYYY-MM-DD(如 I made this on ➕1990-06-14)设置
  • start: 任务开始日期,可通过 [start:: ...]Start Date: 🛫YYYY-MM-DD(如 Task I can start this weekend 🛫2021-08-29)设置
  • scheduled: 任务计划日期,可通过 [scheduled:: ...]Scheduled Date: ⏳YYYY-MM-DD(如 Task I finished ahead of schedule ⏳2021-08-29 ✅2021-08-22)设置
  • annotated: 若有任务自定义 annotations 则为 true,否则为 false
  • parent: 此任务上方任务的行号(如果存在);若是根任务,则该属性为 null
  • blockId: 任务/列表元素的 blockId

下图展示了这几种用法:
Obsidian Dataview

效果如下:
Obsidian Dataview

Querying

Querying 根据条件查询 Annotation 字段并进行动态展示。目前可以通过如下四种方式查询。

Dataview 动态查询语言

Dataview 动态查询语言简称 DQL,提供了基础查询能力,如:

TABLE file.name AS "File", rating AS "Rating" FROM #book

行内表达式

如果想在行内显示 Dataview 的查询结果,可使用 = expression 语法,如插入当前文件名 = this.file.name,插入日期 = date(today),更多表达式参考 Expressions

Dataview JavaScript API

Dataview JavaScript API(下文简称为 Dataview JS)提供了类似 JavaScript API 来访问 Dataview 数据的能力。如:

dv.taskList(dv.pages().file.tasks.where(t => !t.completed));

行内 Dataview JS 表达式

行内表达式一样在行中插入表达式值,语法为 $= expression,如下:

文件最后更新时间为 `$= dv.current().file.mtime`.

下面详细介绍下 DQLDataview JS

DQL

DQL 提供了类似 SQL 的语法,其通用语法如下:

<QueryType> <field> [AS "Column Name"], <field>, ..., <field>
FROM <source>
WHERE <expression>
SORT <expression> [ASC/DESC]
... other data commands

示例仓库中查找所有书籍信息,并展示书名、封面、作者、评分和阅读进查找所有书箱信息,并展示书名、封面、作者、评分和阅读进度:

Table
    WITHOUT ID
    file.name AS 书名,
    embed(link(cover)) AS 封面,
    author AS 作者,
    rating AS 评分,
    status AS 进度
FROM #book AND -"templates"
SORT status DESC

效果如下:
Obsidian Dataview

QueryType

除了 QueryType 为必需字段外,其它字段均可以省略,此时表示仓库中所有的文件。QueryTable 表示视图类型,有如下几个值:

  • TABLE:以表格形式展示视图
  • LIST:以列表形式展示视图
  • TASK:以任务形式展示视图
  • CALENDAR:以日历形式展示视图,文件以 . 的形式展示在日历中指定日期下方。由于显示方式较特殊,所以语法和其他几类视图不同:
    CALENDAR <date>
    FROM <source>
    

field

即展示的字段,即 Annotation 信息。可以原样输出字段,也可以对字段进行修改、计算后再输出。字段可以通过 AS 指定别名,在展示时将显示别名。

默认会展示 ID 字段,由于目前 Dataview 设置中 ID 字段会以 File 展示,所以首列为 File,表示文件,如果想使用其它名称,可在 Dataview 设置中修改。对于 Table/List 两种类型来说,如果不想展示 ID 信息,可以在查询时加上 WITHOUT ID

FROM

表示从哪里查找文件,目前可设置如下几种类型:

  • Tags:从指定 tag(及其所有子 tag)中查找,语法为 FROM #tag
  • 文件夹:从指定文件夹(及其所有子文件夹)查找,语法为 FROM "folder"
  • 单个文件:指定从具体某个文件查找,语法为 FROM "path/file"
  • 文件链接:如果要查找引向某文件的所有文件,使用 FROM [[note]];如果要查找某文件中的所有文件链接,使用 FROM outgoing([[note]]

这些类型可以通过谓词组合使用,如下:

  • and:同时满足多个条件,如 FROM #tag and "folder" 表示查找文件夹 folder 中有 tag 标签的所有文件。
  • or:满足条件之一,如 FROM #tag or "folder" 表示查找文件夹 folder 或有 tag 标签的所有文件。
  • -:表示排除,如 FROM -#tag and "folder" 表示查找文件夹 folder 中不含有 tag 标签的所有文件。

多个条件还可以使用 () 指定优先级,如 FROM #tag and ("folder" or #other-tag) 表示从文件夹 folder 或有 other-tag 标签的文件中再查找有 tag 标签的文件。

WHERE

筛选条件,用来过滤查询结果中 Annotation 不符合条件的文件。如返回一天内有过修改的文件:LIST WHERE file.mtime >= date(today) - dur(1 day)

SORT

对结果排序,有两种排序方式:

  • ASCENDING/ASC:升序,默认排序方式
  • DESCENDING/DESC:降序

可以对多个字段同时排序,优先级从左到右,如 SORT priority DESC, status ASC 表示优先使用 priority 升序排序,如果 priority 相同,再使用 status 降序排序。

GROUP BY

按字段分组展示。

FLATTEN

将结果打开,如书籍信息中有多名作者,若使用 FLATTEN 打平作者,此时该书籍信息会形成多条记录,每条记录的作者只有一位。FLATTEN 一般用于数组或层级列表中。

LIMIT

限制返回结果数,如 LIMIT 10 表示最多返回 10 条记录。

Dataview JS

Dataview JS 允许通过访问数据视图索引和查询引擎来执行任意的 JavaScript 代码,这种方式对复杂视图或与其他插件的交互很有用。相比 Dataview 指定代码类型为 dataview 而言,Dataivew JS 需指定代码类型为 dataviewjs,如下:

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

其中的 dv(或 dataview)为 Dataview JS 隐式提供的变量,用来查询信息、渲染 HTML 和配置视图。

数据数组

Dataview JS 主要是操作数组 DataArray,数据数组有一些常用的方法,如下:

  • where:同 DQL 中的 WHERE
  • filter:是 where 的别名,两者等同。
  • sort:同 DQL 中的 SORT,同样支持 "asc""desc" 两种排序方式。
  • groupBy:同 DQL 中的 GROUP BY
  • limit:同 DQL 中的 LIMIT
  • map:遍历数组并应用函数。
  • find:查找符合条件的元素。
  • join:拼接字符串并返回。

那么如何使用 Dataview JS,如何获取数据数组呢?这里先解释下 Dataview JS 的一些语法。

查询

  • dv.pages(source)
    类似于 Dataview 的 From,可以通过 dv.pages(source) 来查询指定条件的文件,返回文件数组,如 dv.pages("#book") 表示查询所有 tag 为 book 的文件,dv.pages('"folder" or #tag') 表示是查询 folder 目录或标签名为 tag 的所有文件,可以看到其用法大致和 Dataview 的 From 相似。
  • dv.pagePaths(source)
    返回指定条件的文件路径,返回文件路径数组。
  • dv.page(path)
    返回指定路径的文件。
  • dv.current()
    表示当前文件。

渲染

  • dv.el(html-element, text)
    根据指定的 HTML 元素来渲染 text,如 dv.el("b", "qileq.com:分享简单的成长");
  • dv.header(level, text)
    根据指定标题级别渲染 text,如 dv.header(1, "Obsidian 漫游指南");
  • dv.paragraph(text)
    text 渲染为段落,如 dv.paragraph("Dataview 插件概览");
  • dv.span(text)
    text 渲染为行内文本,如 dv.span("Dataview JS 语法");
  • dv.execute(source)
    执行 DQL 查询并插入到当前文件中,如 dv.execute("LIST FROM #tag");
  • dv.executeJs(source)
    执行 Dataivew JS 查询并插入到当前文件中,如 dv.executeJs("dv.list([1, 2, 3])");

Dataviews

  • dv.list(elements)
    以列表形式展示数组,同 DQL 中的 LIST 视图类型,如 dv.list(dv.pages(#book).file.link)
  • dv.taskList(tasks, groupByFile)
    以任务列表的形式展示任务数组,同 DQL 中的 TASK 视图类型。
  • dv.table(headers, elements)
    以表格形式展示数组,并指定表格头,同 DQL 中的 TABLE 视图类型,如下是示例仓库 用 Dataview JS 来展示的语句:

    dv.table(["书名", "封面", "作者", "评分", "进度"], dv.pages('#book AND -"templates"')
    .sort(b => b.status, 'desc')
    .map(b => [b.file.name, dv.fileLink(b.cover, true), b.author, b.rating, b.status]))
    

工具方法

Dataview JS 提供了一些工具方法。

  • dv.array(value)
    根据指定值构成数据数组,如 dv.array([1, 2, 3]) 返回值为 [1, 2, 3] 的数组。
  • dv.fileLink(path, [embed?], [display-name])
    根据指定路径创建文件链接。如 dv.fileLink("测试", false, "测试别名") 表示创建名为“测试别名”的文件链接,其指向文件“测试”。
  • dv.sectionLink(path, section, [embed?], [display?])
    创建段落链接,如 dv.sectionLink("Note", "Header2") 表示 [[Note#Header2]],该语法可参考Obsidian 使用技巧
  • dv.blockLink(path, blockId, [embed?], [display?])
    创建块链接,如 dv.blockLink("Note", "12gdhjg3") 表示 [[Note#^12gdhjg3]]
  • dv.date(text)
    插入日期,如 dv.date("2023-01-01")

以上就是 Dataview JS 的语法了。

如果想看参考案例,可点击这里。如果要优化展示效果的话,还可以将 Dataview 与其它插件组合使用,如 Admonition,具体效果见这里

正文完
 0
管理员
版权声明:本站原创文章,由 管理员 于2024-10-14发表,共计6597字。
转载说明:除特殊说明外本站文章皆由 CC-4.0 协议发布,转载请注明出处。
评论(没有评论)