翻译自官方文档 https://blacksmithgu.github.io/obsidian-dataview/
如有不同之处,请以官方文档为主。
Dataview 有两个主要组件:注释 和 查询
Dataview索引负责不断解析您的知识库中的 markdown 文件和其他元数据,创建一个内存索引,以便对数据进行快速查询。注释在 markdown 页面 、段落 和 task 级别完成,可以在其中使用:
Frontmatter,一个常见的 Markdown 扩展,允许在文档顶部添加任意YAML):
1 |
|
内联字段,一种特定于 Dataview 的方式,以直观的Key::Value语法提供元数据:
1 | # Markdown Page |
如果需要,您可以结合使用这两种方法。Dataview 还添加了大量“隐式”字段,例如file.name文件名、file.size大小等;
你可以在数据注释文档中找到更多详细信息。
一旦你有一些你已经注释的页面,剩下要做的就是查询它们以创建动态表、列表或 JavaScript 视图。
有四种方法可以做到这一点:
``` `
undefined 内联表达式:可以直接嵌入到 Markdown 中的 DQL 表达式,并将在预览模式下显示。请参阅[[3.数据查询]]
We are on page `= this.file.name`.
``` `
This page was last modified at `$= dv.current().file.mtime`.数据索引,支持的是字段。
您可以通过三种不同的方式将字段添加到markdown页面:
--- alias: "document" last-reviewed: 2021-08-17 thoughts: rating: 8 reviewable: false ---
Key:: Value语法,你可以直接将其嵌入到文件中:# Markdown Page Basic Field:: Value **Bold Field**:: Nice!
如果你想在句子中嵌入元数据,或者在同一行中嵌入多个字段,你可以使用括号语法:I would rate this a [rating:: 9]! It was [mood:: acceptable].
file.cday )、关联日期 ( file.day)、文件中的链接 ( file.outlinks)、标签 ( file.tags) 等。一个简单的 Markdown 页面,有以下两种用户定义的添加元数据的方式:
--- duration: 4 hours reviewed: false ---# Movie X **Thoughts**:: It was decent. **Rating**:: 6
Dataview 会自动为每个页面添加大量元数据:
file.name:文件标题(字符串)。file.folder:该文件所属文件夹的路径。file.path:完整的文件路径(字符串)。file.link:文件的链接(链接)。file.size:文件的大小(以字节为单位)(数字)。file.ctime:文件的创建日期(日期+时间)。file.cday:文件的创建日期(日期)。file.mtime:文件最后修改的日期(日期+时间)。file.mday:文件最后修改的日期(日期)。file.tags:笔记中所有唯一标签的数组。子标签按每个级别细分,因此#Tag/1/A将存储在数组中[#Tag, #Tag/1, #Tag/1/A]。file.etags:注释中所有显式标签的数组;不和file.tags一样, 不包括子标签。file.inlinks:此文件的所有传入链接的数组。file.outlinks:此文件中所有传出链接的数组。file.aliases:笔记的所有别名的数组。file.tasks:此文件中所有任务(即,- [ ] blah blah blah)的数组。如果文件在其标题(或表单yyyy-mm-dd或yyyymmdd)中有日期,或者有一个Date字段/内联字段,它还具有以下属性:
file.day:与文件关联的日期。使用内联字段语法使用元数据注释您的任务清单(即表单的行):- [ ] blah blah blah
1 | - [ ] Hello, this is some [metadata:: value]! |
为了支持“常见用例”,Dataview 了解一些常见数据的简写,您可能希望使用以下命令注释任务:
语法
🗓️YYYY-MM-DD✅YYYY-MM-DD➕YYYY-MM-DD如果你不喜欢表情符号,可以对这些字段进行文本注释([due:: ]、[created:: ]、 [completion:: ])。
与页面一样,Dataview 为每个任务添加了许多隐式字段:
completed:这个 特定的 任务是否已经完成;这不考虑任何子任务的完成/未完成。fullyCompleted:此任务及其所有子任务是否已完成。text: 这个任务的文本line:此任务显示的行path:此任务所在文件的完整路径。section:此任务所在部分的链接。link: 指向该任务附近最近的可链接块的链接;对于制作指向任务的链接很有用。subtasks:此任务的所有子任务。real: 如果是true,这是一个真正的任务;否则,它是任务上方/下方的列表元素。completion:任务完成的日期。如果没有注释,将默认为文件修改时间。due:任务的到期日期(如果有的话)。created:创建任务的日期。如果没有注释,则默认为文件创建时间。annotated:如果任务有任何自定义注释,则为真,否则为假。dataview 中的所有字段都有一个 type ,它决定了 dataview 将如何呈现、排序和操作该字段。Dataview 了解几种不同的字段类型以涵盖常见用例:
文本:默认的。如果字段不匹配更具体的类型,则它只是纯文本。
Example:: This is some normal text.
Number : 像 ‘6’ 和 ‘3.6’ 这样的数字。
Example:: 6 Example:: 2.4 Example:: -80
Boolean : true/false,逻辑值
Example:: true Example:: false
日期:ISO8601日期的一般形式YYYY-MM[-DDTHH:mm:ss.nnn+ZZ]。月后的一切都是可选的。
Example:: 2021-04-18 Example:: 2021-04-18T04:19:35.000 Example:: 2021-04-18T04:19:35.000+06:30
持续时间:<time> <unit>表单的持续时间,例如6 hours或4 minutes。常见的英文缩写如 6hrsor2m 您可以使用可选的逗号分隔符指定多个单位:6 hours, 4 minutes 或 6hr4min.
Example:: 7 hours Example:: 4min Example:: 16 days Example:: 9 years, 8 months, 4 days, 16 hours, 2 minutes Example:: 9 yrs 8 min
链接:普通Obsidian链接,如[[Page]]或[[Page|Page Display]]。
如果你在 frontmatter 中引用链接,则需要引用它,如下所示:key: "[[Link]]". 这是默认的 Obsidian 支持的行为。
Example:: [[A Page]] Example:: [[Some Other Page|Render Text]]
List:其他数据视图字段的列表。在 YAML 中,这些被定义为正常的 YAML 列表;对于内联字段,它们只是逗号分隔的列表。
Example:: 1, 2, 3 Example:: "yes", "or", "no"
对象:名称到数据视图字段的映射。这些只能在 YAML frontmatter 中定义,使用正常的 YAML 对象语法:
field: value1: 1 value2: 2 ...
有4种方式实现这一点,并且在库update 的时候可以重新加载
dataview查询语言是一种简单的、类似 SQL 的语言,用于快速创建视图的语言。它支持基本的算术和比较运算,适用于基本应用程序。您使用带注释的代码块创建数据视图查询dataview:
```dataview TABLE rating AS "Rating", summary AS "Summary" FROM #games SORT rating DESC ```
查询可以直接嵌入页面中
= date(today),或来自另一个页面的字段 = [[Page]].value使用内联代码块创建内联查询:`= this.file.name`
内联 DQL 表达式是使用查询语言表达式语言编写的。您可以在 Dataview 设置中配置内联查询以使用不同的前缀(如dv:或)。~
dataview[[5.0.JavascriptAPI]]为您提供 JavaScript 的全部功能,并提供用于拉取 Dataview 数据和执行查询的 DSL,允许您创建任意复杂的查询和视图。与查询语言类似,您可以通过带注释的代码块创建 Dataview JS 块dataviewjs:
```dataviewjs let pages = dv.pages("#books and -#books/finished").where(b => b.rating >= 7); for (let group of pages.groupBy(b => b.genre)) { dv.header(group.key); dv.list(group.rows.file.name); } ```
dv 在 JS dataview 块中,您可以通过变量访问完整的 dataview API
与查询语言类似,您可以编写 JS 内联查询,它可以让您直接嵌入计算出的 JS 值。您可以通过内联代码块创建 JS 内联查询:
`$= dv.current().file.mtime`
在 inline DataviewJS 中,您可以访问dv变量,就像在代码块中访问dataviewjs,并且可以进行所有相同的调用。
结果应该被看作 JavaScript 值的结果,Dataview 将自动适当地呈现该值。
Dataview查询语言是一种简单的、结构化的、自定义的查询语言,用于快速创建数据的视图。支持:
该查询语言支持以下视图类型,描述如下:
一般格式
```dataview TABLE|LIST|TASK <field> [AS "Column Name"], <field>, ..., <field> FROM <source> (like #tag or "folder") WHERE <expression> (like 'field = value') SORT <expression> [ASC/DESC] (like 'field ASC') ... other data commands ```
查询类型和数据命令请查看[[4.1.查询]]
表达式:能够产生值的量
1 | # 常规 |
字符串型、字面值型、算数型、比较型、数组对象索引、函数调用、lambda表达式型
特定类型的交互和值
大多数dataview类型都有和运算符的特定的操作,或者有额外的能被引用的属性
Date
Durations
Links[[Link]].value
字面量是表示常量的表达式
包括一般类型、日期类型、持续时间类型
具体情况在[[4.2.字面值]]
dataview的source定义了一系列的file task 或者其他的数据对象
source 被Dataview内部引用,它支持3种source类型
#tag"folder""folder/file.md"[[note]],也可以使用[[]] 引用本文件outgoing([[note]])可以使用and、or链接这些过滤器
函数提供了更高级的功能,具体函数查看[[4.3.函数]]
最简单的视图,只是呈现与查询匹配的页面列表(或自定义字段)。
语法
LIST FROM <source>
查询
LIST FROM #games/mobas OR #games/crpg
除了每个匹配文件之外,您还可以通过在 之后添加一个表达式来呈现单个计算值LIST:
语法
LIST <expression> FROM <source>
查询
LIST "File Path: " + file.path FROM "4. Archive"
如果您不希望列表视图中包含filename/group key,您可以使用LIST WITHOUT ID:
语法
LIST WITHOUT ID <expression> FROM <source>
查询
LIST WITHOUT ID file.path FROM "4. Archive"
表格支持页面数据的表格视图。您可以通过提供要呈现的 YAML frontmatter 字段,使用逗号分隔列表来构造一个table,如下所示:
TABLE file.day, file.mtime FROM <source>
使用以下AS语法选择标题名称来呈现计算字段:
TABLE (file.mtime + dur(1 day)) AS next_mtime, ... FROM <source>
示例:
TABLE time-played AS "Time Played", length AS "Length", rating AS "Rating" FROM #game SORT rating DESC
如果您不想在输出中使用默认的“file”或“group”字段,可以使用 TABLE WITHOUT ID:
询问
TABLE WITHOUT ID time-played AS "Time Played", length AS "Length", rating AS "Rating" FROM #game SORT rating DESC
任务视图呈现其页面与给定谓词匹配的所有任务。
语法
TASK FROM <source>
查询
TASK FROM "dataview"
您可以使用典型的数据视图语句根据需要在这些查询中过滤 ( WHERE)、分组 ( GROUP BY)、排序 ( SORT)
语法
TASK FROM <source> WHERE <predicate> ...
查询
TASK FROM "dataview" WHERE !completed GROUP BY file.folder
日历视图呈现与日历视图中的查询匹配的所有页面,使用给定的日期表达式来选择呈现页面的日期。
语法
CALENDAR <date> FROM <source>
查询
CALENDAR file.mtime FROM "dataview"
输出
输出将是一个日历,在 dataview 目录中每个文件显示一个点。点在文件被修改的日期。
dataview 查询可以由不同的命令组成。命令按顺序执行,命令可以重复(例如,多个WHERE 块或多个GROUP BY块)。
该FROM语句确定最初将收集哪些页面,并将其传递给其他命令以进一步过滤。
可以从任何[[4.0.查询语言#来源]]进行选择,可以按文件夹、标签或传入/传出链接。
FROM #tag.FROM "folder".[[note]],请使用FROM [[note]].[[note]](即该文件中的所有链接),使用FROM outgoing([[note]]).您可以组合这些过滤器,使用and和or进一步过滤。
#tag and "folder"将返回所有页面的folder和#tag.[[Food]] or [[Exercise]]将给出任何链接到[[Food]]OR的页面[[Exercise]]。您还可以使用以下方法“排除”来源以获取与来源不匹配的任何内容:
-#tag将排除具有给定标签的文件。#tag and -"folder"将仅包括标记#tag为不在"folder".过滤字段上的页面。结果为true才会被选择
WHERE <clause>
获取最近 24 小时内修改的所有文件:
LIST WHERE file.mtime >= date(today) - dur(1 day)
查找所有未标记为完成且超过一个月的项目:
LIST FROM #projects WHERE !completed AND file.ctime <= date(today) - dur(1 month)
按一个或多个字段对所有结果进行排序。
SORT date [ASCENDING/DESCENDING/ASC/DESC]
您还可以提供多个字段进行排序。将根据第一个字段进行排序。然后,如果出现相等,则将使用第二个字段对相等字段进行排序。如果仍然存在平局,则第三个排序将解决它,依此类推。
SORT field1 [ASCENDING/DESCENDING/ASC/DESC], ..., fieldN [ASC/DESC]
将所有结果分组到一个字段中。每个唯一字段值产生一行,它有 2 个属性:一个对应于被分组的字段,一个rows数组字段包含所有匹配的页面。
GROUP BY field GROUP BY (computed_field) AS name
在每一行中展平一个数组,为数组中的每个条目产生一个结果行。
FLATTEN field FLATTEN (computed_field) AS name
例如,将authors每个文献注释中的字段展平,为每位作者提供一行:
查询
TABLE authors FROM #LiteratureNote FLATTEN authors
将结果限制为最多 N 个值。
LIMIT 5
命令是按照它们编写的顺序处理的,所以下面对已经限制后的结果进行排序:
LIMIT 5 SORT date ASCENDING
是或者运算后是常量的表达式、常量
| 字面量 | 解释 |
|---|---|
| 0 | 数字0 |
| 123 | 数字123 |
| -123 | 数字-123 |
| “HelloWorld” | string类型的变量 |
[[Link]] |
连接到文件Link的链接 |
| [1,2,3] | 数组 |
| {a:1,b:2} | 对象 |
date也是[[4.3.函数]]
以下都是字面值:
dur(1 s, 2 m, 3 h)
dur(1 s 2 m 3 h)
dur(1s 2m 3h)
dur(1second 2min 3h)
以下给出1秒和23秒的实例
dur(1 s)
dur(1 sec)
dur(1 second)
dur(23 s)
dur(23 secs)
dur(23 seconds)
m、min、minute
m、mins、minutes
h、hr、hour
h、hrs、hours
d、day
d、days
w、wk、week
w、wks、weeks
mo、month
mo、months
yr、year
yrs、years
Dataview 函数提供了更高级的方法来操作数据。
大多数函数既可以应用于单个值(如number、string、date等),也可以应用于这些值的列表。如果将函数应用于列表,则在将函数应用于列表中的每个元素后,它也会返回一个列表。例如:
lower("YES") = "yes" lower(list("YES", "NO")) = list("yes", "no") replace("yes", "e", "a") = "yas" replace(list("yes", "ree"), "e", "a") = list("yas", "raa")
创造值的构造函数。
object(key1, value1, ...)使用给定的键和值创建一个新对象。键和值应该在调用中交替,键应该始终是字符串/文本。
object() => empty object object("a", 6) => object which maps "a" to 6 object("a", 4, "c", "yes") => object which maps a to 4, and c to "yes"
list(value1, value2, ...)创建一个包含给定值的新列表。
list() => empty list list(1, 2, 3) => list with 1, 2, and 3 list("a", "b", "c") => list with "a", "b", and "c"
date(any)如果可能,从提供的字符串、日期或链接对象解析日期,否则返回 null。
date("2020-04-18") = <date object representing April 18th, 2020> date([[2021-04-16]]) = <date object for the given page, refering to file.day>
dur(any)从提供的字符串或持续时间解析持续时间,失败时返回 null。
dur(8 minutes) = <8 minutes> dur("8 minutes, 4 seconds") = <8 minutes, 4 seconds> dur(dur(8 minutes)) = dur(8 minutes) = <8 minutes>
number(string)从给定字符串中解析出第一个数字,返回它。如果字符串中没有数字,则返回 null。
number("18 years") = 18 number(34) = 34 number("hmm") = null
string(any)将任何值转换为“合理”的字符串表示形式。与直接在查询中使用值相比,这有时会产生不那么漂亮的结果——它主要用于将日期、持续时间、数字等强制转换为字符串以进行操作。
string(18) = "18" string(dur(8 hours)) = "8 hours" string(date(2021-08-15)) = "August 15th, 2021"
link(path, [display])从给定的文件路径或名称构造一个链接对象。如果提供了两个参数,则第二个参数是链接的显示名称。
link("Hello") => link to page named 'Hello' link("Hello", "Goodbye") => link to page named 'Hello', displays as 'Goodbye'
elink(url, [display])构造一个指向外部 url 的链接(如www.google.com)。如果提供了两个参数,则第二个参数是链接的显示名称。
elink("www.google.com") => link element to google.com elink("www.google.com", "Google") => link element to google.com, displays as "Google"
round(number, [digits])将数字四舍五入到给定的位数。如果未指定第二个参数,则四舍五入到最接近的整数;否则,四舍五入到给定的位数。
round(16.555555) = 7 round(16.555555, 2) = 16.56
–
操作容器对象内部的值的操作。
contains(object|list|string, value)检查给定的容器类型是否具有给定的值。根据第一个参数是对象、列表还是字符串,此函数的行为略有不同。
对于对象,检查对象是否具有给定名称的键。例如,
contains(file, "ctime") = true contains(file, "day") = true (if file has a date in its title, false otherwise)
对于列表,检查是否有任何数组元素等于给定值。例如,
contains(list(1, 2, 3), 3) = true contains(list(), 1) = false
对于字符串,检查给定值是否是字符串的子字符串(即,在字符串内部)。
contains("hello", "lo") = true contains("yes", "no") = false
extract(object, key1, key2, ...)从一个对象中提取多个字段,创建一个仅包含这些字段的新对象。
extract(file, "ctime", "mtime") = object("ctime", file.ctime, "mtime", file.mtime) extract(object("test", 1)) = object()
sort(list)对列表进行排序,按排序顺序返回一个新列表。
sort(list(3, 2, 1)) = list(1, 2, 3) sort(list("a", "b", "aa")) = list("a", "aa", "b")
reverse(list)反转一个列表,以相反的顺序返回一个新列表。
reverse(list(1, 2, 3)) = list(3, 2, 1) reverse(list("a", "b", "c")) = list("c", "b", "a")
length(object|array)返回对象中的字段数或数组中的条目数。
length(list()) = 0 length(list(1, 2, 3)) = 3 length(object("hello", 1, "goodbye", 2)) = 2
sum(array)对数组中的所有数值求和
sum(list(1, 2, 3)) = 6
all(array)true仅当数组中的所有值都为真时才返回。您还可以将多个参数传递给此函数,在这种情况下,它true仅在所有参数都为真时才返回。
all(list(1, 2, 3)) = true all(list(true, false)) = false all(true, false) = false all(true, true, true) = true
any(array)true如果数组中的任何值是真实的,则返回。您还可以将多个参数传递给此函数,在这种情况下,true如果任何参数为真,它就会返回。
any(list(1, 2, 3)) = true any(list(true, false)) = true any(list(false, false, false)) = false all(true, false) = true all(false, false) = false
none(array)true如果数组中没有一个值是真实的,则返回。
none([]) = true none([false, false]) = true none([false, true]) = false none([1, 2, 3]) = false
join(array)将数组中的元素连接到单个字符串中(即,将它们全部呈现在同一行上)。如果提供了第二个参数,则每个元素将由给定的分隔符分隔。
join(list(1, 2, 3)) = "1, 2, 3" join(list(1, 2, 3), " ") = "1 2 3" join(6) = "6" join(list()) = ""
filter(array, predicate)根据谓词过滤数组中的元素,返回匹配的元素的新列表。
filter([1, 2, 3], (x) => x >= 2) = [2, 3] filter(["yes", "no", "yas"], (x) => startswith(x, "y")) = ["yes", "yas"]
map(array, func)将函数应用于数组中的每个元素,返回映射结果的列表。
map([1, 2, 3], (x) => x + 2) = [3, 4, 5] map(["yes", "no"], (x) => x + "?") = ["yes?", "no?"]
regexmatch(pattern, string)检查给定字符串是否与给定模式匹配(使用 JavaScript 正则表达式引擎)。
regexmatch("\w+", "hello") = true regexmatch(".", "a") = true regexmatch("yes|no", "maybe") = false
regexreplace(string, pattern, replacement)用,替换_正则表达式_ pattern匹配的所有实例。这在底层使用了 JavaScript 替换方法,因此您可以使用特殊字符,例如引用第一个捕获组,依此类推。string``replacement``$1
regexreplace("yes", "[ys]", "a") = "aea" regexreplace("Suite 1000", "\d+", "-") = "Suite -"
replace(string, pattern, replacement)pattern将in的所有实例替换string为replacement。
replace("what", "wh", "h") = "hat" replace("The big dog chased the big cat.", "big", "small") = "The small dog chased the small cat." replace("test", "test", "no") = "no"
lower(string)将字符串转换为全部小写。
lower("Test") = "test" lower("TEST") = "test"
upper(string)将字符串转换为全部大写。
upper("Test") = "TEST" upper("test") = "TEST"
split(string, delimiter, [limit])在给定的分隔符字符串上拆分字符串。如果提供了第三个参数,它会限制发生的拆分次数。分隔符字符串被解释为正则表达式。如果分隔符中有捕获组,则将匹配项拼接到结果数组中,不匹配的捕获项为空字符串。
split("hello world", " ") = list("hello", "world") split("hello world", "\s") = list("hello", "world") split("hello there world", " ", 2) = list("hello", "there") split("hello there world", "(t?here)") = list("hello ", "there", " world") split("hello there world", "( )(x)?") = list("hello", " ", "", "there", " ", "", "world")
startswith(string, prefix)检查字符串是否以给定前缀开头。
startswith("yes", "ye") = true startswith("path/to/something", "path/") = true startswith("yes", "no") = false
endswith(string, suffix)检查字符串是否以给定的后缀结尾。
endswith("yes", "es") = true endswith("path/to/something", "something") = true endswith("yes", "ye") = false
padleft(string, length, [padding])通过在左侧添加填充将字符串填充到所需的长度。如果省略填充字符,则默认使用空格。
padleft("hello", 7) = " hello" padleft("yes", 5, "!") = "!!yes"
padright(string, length, [padding])等效于padleft,但改为向右填充。
padright("hello", 7) = "hello " padright("yes", 5, "!") = "yes!!"
default(field, value)如果field为空,则返回value;否则返回field。对于用默认值替换空值很有用。例如,要显示尚未完成的项目,请使用"incomplete"它们的默认值:
default(dateCompleted, "incomplete")
默认值在两个参数中都是矢量化的;如果您需要在列表参数上显式使用 default ,请使用ldefault,它与 default 相同,但未矢量化。
default(list(1, 2, null), 3) = list(1, 2, 3) ldefault(list(1, 2, null), 3) = list(1, 2, null)
choice(bool, left, right)原始 if 语句 - 如果第一个参数为真,则返回左;否则,返回正确。
choice(true, "yes", "no") = "yes" choice(false, "yes", "no") = "no" choice(x > 4, y, z) = y if x > 4, else z
striptime(date)去掉日期的时间部分,只留下年、月和日。如果您不关心时间,则适合日期比较。
striptime(file.ctime) = file.cday striptime(file.mtime) = file.mday
localtime(date)将固定时区的日期转换为当前时区的日期。
meta(link)获取包含链接元数据的对象。当您访问链接上的属性时,您得到的是链接文件中的属性值。该meta功能可以访问链接本身的属性。
返回的对象有几个属性meta:
meta(link).display获取链接的显示文本,如果链接没有定义的显示文本,则为 null。
meta([[2021-11-01|Displayed link text]]).display = "Displayed link text" meta([[2021-11-01]]).display = null
meta(link).embed真或假取决于链接是否为嵌入。这些是以感叹号开头的链接,例如 ![[Some Link]].
meta(link).path获取链接的路径部分。
meta([[My Project]]).path = "My Project" meta([[My Project#Next Actions]]).path = "My Project" meta([[My Project#^9bcbe8]]).path = "My Project"
meta(link).subpath获取链接的子路径。对于文件中标题的链接,子路径将是标题的文本。对于块的链接,子路径将是块 ID。如果这些情况都不适用,则子路径将为空。
meta([[My Project#Next Actions]]).subpath = "Next Actions" meta([[My Project#^9bcbe8]]).subpath = "9bcbe8" meta([[My Project]]).subpath = null
这可用于选择特定标题下的任务。
```dataview task where meta(section).subpath = "Next Actions" ```
meta(link).type根据链接是链接到整个文件、文件中的标题还是文件中的块,具有值“文件”、“标题”或“块”。
meta([[My Project]]).type = "file" meta([[My Project#Next Actions]]).type = "header" meta([[My Project#^9bcbe8]]).type = "block"