Dataview Plugin
· Dataview docs · Obsidian Example Vault for Dataview Queries · #note/sink ·
TOC
Inline
For those wanting a more natural-looking annotation, Dataview supports "inline" fields via a Key:: Value
syntax that you can use everywhere in your file. This allows you to write your queryable data right where you need it - for example in the middle of a sentence.
If your inline field has an own line, without any content beforehand, you can write it like this:
# Markdown Page Basic Field:: Some random Value **Bold Field**:: Nice!
All content after the ::
is the value of the field until the next line break.
Mind the ::
You need to use a double colon ::
between key and value when using inline fields, contrary to YAML Frontmatter fields where one colon is enough.
If you want to embed metadata inside sentences, or multiple fields on the same line, you can use the bracket syntax and wrap your field in square brackets:
I would rate this a [rating:: 9]! It was [mood:: acceptable].
Fields on list items and tasks
When you want to annotate a list item, e.g. a task, with metadata, you always need to use the bracket syntax (because the field is not the only information in this line)
- [ ] Send an mail to David about the deadline [due:: 2022-04-05].
Bracketed inline fields are the only way to explicitly add fields to specific list items, YAML frontmatter always applies to the whole page (but is also available in context of list items.)
Implicit fields
Field Name | Data Type | Description |
---|---|---|
file.name | Text | The file name as seen in Obsidians sidebar. |
file.folder | Text | The path of the folder this file belongs to. |
file.path | Text | The full file path, including the files name. |
file.ext | Text | The extension of the file type; generally md. |
file.link | Link | A link to the file. |
file.size | Number | The size (in bytes) of the file. |
file.ctime | Date | with Time The date that the file was created. |
file.cday | Date | The date that the file was created. |
file.mtime | Date | with Time The date that the file was last modified. |
file.mday | Date | The date that the file was last modified. |
file.tags | List | A list of all unique tags in the note. Subtags are broken down by each level, so #Tag/1/A will be stored in the list as [#Tag, #Tag/1, #Tag/1/A]. |
file.etags | List | A list of all explicit tags in the note; unlike file.tags, does not break subtags down, i.e. [#Tag/1/A] |
file.inlinks | List | A list of all incoming links to this file, meaning all files that contain a link to this file. |
file.outlinks | List | A list of all outgoing links from this file, meaning all links the file contains. |
file.aliases | List | A list of all aliases for the note as defined via the YAML frontmatter. |
file.tasks | List | A list of all tasks (I.e., [ ] some task) in this file. |
file.lists | List | A list of all list elements in the file (including tasks); these elements are effectively tasks and can be rendered in task views. |
file.frontmatter | List | Contains the raw values of all frontmatter in form of key value text values; mainly useful for checking raw frontmatter values or for dynamically listing frontmatter keys. |
file.day | Date | Only available if the file has a date inside its file name (of form yyyy-mm-dd or yyyymmdd), or has a Date field/inline field. |
file.starred | Boolean | if this file has been starred via the Obsidian Core Plugin "Starred Files". |
Tasks and tasks list metadata
Just like pages, you can also add fields on list item and task level to bind it to a specific task as context. For this you need to use the inline field syntax:
- [ ] Hello, this is some [metadata:: value]!
- [X] I finished this on [completion:: 2021-08-15].
For supporting "common use cases", Dataview understands a few shorthands for some fields you may want to annotate task with:
There are two specifics to these emoji-shorthands. First, they omit the inline field syntax (no [🗓️:: YYYY-MM-DD]
needed) and secondly, they map to a textual field name data-wise:
Field name | Short hand syntax |
---|---|
due | 🗓️YYYY-MM-DD |
completion | ✅YYYY-MM-DD |
created | ➕YYYY-MM-DD |
start | 🛫YYYY-MM-DD |
scheduled | ⏳YYYY-MM-DD |
his means if you want to query for all tasks that are completed 2021-08-22, you'll write:
TASK
WHERE completion = date("2021-08-22")
As with pages, Dataview adds a number of implicit fields to each task or list item:
Inheritance of Fields
Tasks inherit all fields from their parent page - so if you have a rating field in your page, you can also access it on your task in a TASK Query.
Field name | Data Type Description | |
---|---|---|
status | Text | The completion status of this task, as determined by the character inside the [ ] brackets. Generally a space " " for incomplete tasks and a "x" for complete tasks, but allows for plugins which support alternative task statuses. |
checked | Boolean | Whether or not this task status is empty, meaning it has a space in its [ ] brackets |
completed | Boolean | Whether or not this specific task has been completed; this does not consider the completionnon-completion of any child tasks. A task is explicitly considered "completed" if it has been marked with an 'x'. If you use a custom status, i.e. [-], checked will be true, whereas completed will be false. |
fullyCompleted | Boolean | Whether or not this task and all of its subtasks are completed. |
text | Text | The plain text of this task, including any metadata field annotations. |
visual | Text | The text of this task, which is rendered by Dataview. It can be modified to render arbitary text. |
line | Number | The line of the file this task shows up on. |
lineCount | Number | The number of Markdown lines that this task takes up. |
path | Text | The full path of the file this task is in. Equals to file.path for pages |
section | Link | link to the section this task is contained in. |
tags | List | Any tags inside of the text task. |
outlinks | List | Any links defined in this task. |
link | Link | link to the closest linkable block near this task; useful for making links which go to the task. |
children | List | ny subtasks or sublists of this task. |
task | Boolean | If true, this is a task; otherwise, it is a regular list element. |
annotated | Boolean | True if the task text contains any metadata fields, false otherwise. |
parent | Number | The line number of the task above this task, if present; will be null if this is a root-level task. |
blockId | Text | The block ID of this task / list element, if one has been defined with the |
syntax; otherwise null. |
For TASK queries your tasks are the top level information and can be used without any prefix:
TASK
WHERE !fullyCompleted
LIST
WHERE any(file.tasks, (t) => !t.fullyCompleted)
DQL
Query format
-
QUERY: Choosing an output format of your output (the Query Type)
- TABLE
- LIST
- TASK
- CALENDAR
-
FROM: Fetch pages from a certain source, i.e. a tag, folder or link
FROM "Books"
- all links to the noteFROM outgoing([[Dashboard]])
- all outgoing linksFROM [[]]
- links to current noteFROM status/open OR status/wip
FROM (#assignment AND "30 School") OR ("30 School/32 Homeworks" AND outgoing([[School Dashboard Current To Dos]]))
FROM -#tag
will exclude files which have the given tagFROM #tag and -"folder"
will only include files tagged#tag
which are NOT in"folder"
FROM #tag and ("folder" or #other-tag)
-
WHERE: Filtering pages/data by simple operations on fields, like comparison, existence checks, and so on
WHERE !completed AND file.ctime <= date(today) - dur(1 month)
WHERE contains(L.author, "Surname")
WHERE typeof(contacts) = "array" AND contains(contacts, [[Mr. L]])
WHERE contains(file.name, "WIP")
WHERE string(file.day.year) = split(this.file.name, "-W")[0]
WHERE file.day.year = 2022
-
FLATTEN: Transforming fields for displaying, i.e. with calculations or splitting up multi-value fields
FLATTEN field
FLATTEN (computed_field) AS name
-
SORT: Sorting results based on fields
SORT field1 [ASCENDING/DESCENDING/ASC/DESC], ..., fieldN [ASC/DESC]
-
GROUP BY: Grouping results based on fields
GROUP BY field
GROUP BY (computed_field) AS name
-
LIMIT: Limiting your result count
LIMIT 5
The Query Type is the only mandatory command in a query. Everything else is optional.
Expressions
Dataview query language expressions are anything that yields a value:
- all fields
- all literals
- and computed values, like field - 9 of function calls.
# Literals
1 (number)
true/false (boolean)
"text" (text)
date(2021-04-18) (date)
dur(1 day) (duration)
[[Link]] (link)
[1, 2, 3] (list)
{ a: 1, b: 2 } (object)
#Lambdas (functions)
(x1, x2) => ... (lambda)
# References
field (directly refer to a field)
simple-field (refer to fields with spaces/punctuation in them like "Simple Field!")
a.b (if a is an object, retrieve field named 'b')
a[expr] (if a is an object or array, retrieve field with name specified by expression 'expr')
f(a, b, ...) (call a function called `f` on arguments a, b, ...)
# Arithmetic
a + b (addition)
a - b (subtraction)
a * b (multiplication)
a / b (division)
a % b (modulo / remainder of division)
# Comparison
a > b (check if a is greater than b)
a < b (check if a is less than b)
a = b (check if a equals b)
a != b (check if a does not equal b)
a <= b (check if a is less than or equal to b)
a >= b (check if a is greater than or equal to b)
# Strings
a + b (string concatenation)
a * num (repeat string <num> times)
# Special Operations
[[Link]].value (fetch `value` from page `Link`)
Functions
# Functions on lists
lower("YES") = "yes"
lower(["YES", "NO"]) = ["yes", "no"]
replace("yes", "e", "a") = "yas"
replace(["yes", "ree"], "e", "a") = ["yas", "raa"]
# Constructors
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"
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(8 minutes) = <8 minutes>
number("18 years") = 18
number(34) = 34
number("hmm") = null
link("Hello") => link to page named 'Hello'
link("Hello", "Goodbye") => link to page named 'Hello', displays as 'Goodbye'
embed(link("Hello.png")) => embedded link to the "Hello.png" image, which will render as an actual image.
elink("www.google.com", "Google") => link element to google.com, displays as "Google"
Numeric
round(number, [digits])
min(a, b, ..) or array, or strings by length
max(a, b, ...) or array, or strings by length
sum(array) sum(nonnull([null, 1, 8])) = 9
product(array)
average(array)
minby(array, function) minby([1, 2, 3], (k) => 0 - k) => 3
maxby(array, function) maxby(this.file.tasks, (k) => k.due) => (latest due)
contains(object|list|string, value) contains("Hello", "Lo") = false
icontains(object|list|string, value) icontains("Hello", "Lo") = true
econtains(object|list|string, value) econtains("Hello", "lo") = true, econtains(["this","is","example"], "is") = true
contains(file, "ctime") = true For objects, checks if the object has a key with the given name
containsword(list|string, value) For strings, it checks if the word is present in the given string
For lists, it returns a list of booleans indicating
if the word's exact case insensitive match was found
extract(object, key1, key2, ...) Pulls multiple fields out of an object, creating a new object with just those fields
sort(list)
reverse(list)
length(object|array)
nonnull(array) Return a new array with all null values removed
all(array) Returns true only if ALL values in the array are truthy
all([1, 2, 3]) = true
all(["apple", "pie", 3], (x) => typeof(x) = "string") = false
any(array) Returns true if ANY of the values in the array are truthy
none(array) Returns true if NONE of the values in the array are truthy
none(["Apple", "Pi", "Banana"], (x) => startswith(x, "A")) = false
join(array, [delimiter]) join(list(1, 2, 3), " ") = "1 2 3"
filter(array, predicate) Filters elements in an array according to the predicate, returning a new list
filter([1, 2, 3], (x) => x >= 2) = [2, 3]
filter(["yes", "no", "yas"], (x) => startswith(x, "y")) = ["yes", "yas"]
map(array, func) Applies the function to each element in the array, returning a list
map([1, 2, 3], (x) => x + 2) = [3, 4, 5]
map(["yes", "no"], (x) => x + "?") = ["yes?", "no?"]
Strings
regextest(pattern, string) Checks if the given regex pattern can be found (JavaScript regex engine)
regextest("\w+", "hello") = true
regextest("what", "what's up dog?") = true
regexreplace(string, pattern, replacement) regexreplace("yes", "[ys]", "a") = "aea"
regexreplace("Suite 1000", "\d+", "-") = "Suite -"
lower(string)
upper(string)
split(string, delimiter, [split limit])
startswith(string, prefix) startswith("path/to/something", "path/") = true
endswith(string, suffix) endswith("path/to/something", "something") = true
padleft(string, length, [padding symbol])
padright(string, length, [padding symbol])
substring(string, start, [end])
truncate(string, length, [suffix])
Utility
default(field, value) If `field` is null, return `value`. Vectorized in both arguments
default(list(1, 2, null), 3) = list(1, 2, 3)
ldefault(field, value) Same for lists
ldefault(list(1, 2, null), 3) = list(1, 2, null)
choice(bool, left, right) If the first is truthy, returns left; otherwise - right
choice(x > 4, y, z) = y (if x > 4, else z)
striptime(date) Strip the time component of a date to year, month, and day
dateformat(date|datetime, string) Format a Dataview date
dateformat(file.ctime,"yyyy-MM-dd") = "2022-01-05"
dateformat(file.ctime,"HH:mm:ss") = "12:18:04"
dateformat(file.mtime,"ffff") = "Wednesday, August 6, 2014 ..."
localtime(date)
meta(link) Get an object containing metadata of a link
meta(link).display meta(Displayed text).display = "Displayed text"
meta(link).embed True or false depending on whether the link is an embed
meta(link).path Get the path portion of a link
meta([[My Project#Next Actions]]).path = "My Project"
meta(link).subpath meta([[My Project#Next Actions]]).subpath = "Next Actions"
meta([[My Project]]).subpath = null
meta(link).type Has the value "file", "header", or "block"