Obsidian Dataview

213次阅读
没有评论

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

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

如果说 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 协议发布,转载请注明出处。
评论(没有评论)