It’s doable, but I’m not sure how easy or robust such a query would be. Especially, when you got the date in a sublist of the item I’m reckoning you actually want to list.
Basically your query would then need to:
- Look at every list item which are having children. For each of those children:
- Look at any outlinks of that child, and check if it’s a date link of the upcoming week
- If it matches, return the entry
If in addition you want to only list that child, it gets even hairier…
The road towards the final query
Put the following in a file in your vault, and replace the FROM "..."
part with the full exact path to this file.
---
Tags: f96355
---
questionUrl:: http://forum.obsidian.md/t//96355
- Talked to [[Mom]]
- Has an appointment on [[2025-02-11]] with [[John Doe]]
- Doesn't have anything to do with [[somewhere]] or [[Someone]]
- Talked to [[Dad]]
- Had an appointment yesterday, that is [[Journal/2025/02/2025-02-07]]
- And another one on [[2025-02-16]]
- Talked to someone uninteresting
- Didn't even talk to this guy
- But he was surely uninteresting
- Wow, post this query
- Explain this query on [[2025-02-08]]
## Base query
```dataview
TABLE WITHOUT ID
item.text as "Text", length(item.children) as "Child count"
FROM "ForumStuff/f96/f96355/t96355 test 2025-02-08.md"
FLATTEN file.lists as item
```
## Limit down to items with children and outlinks
```dataview
TABLE WITHOUT ID
item.text as "Text", length(item.children) as "Child count", candidates as "Outlink candidates"
, map(candidates, (m) => meta(m)) as "meta on outlinks"
, map(candidates, (m) => m.file.name) as "existing file names"
, flat(map(candidates, (m) => slice(split(meta(m).path, "/"), -1))) as "split path"
FROM "ForumStuff/f96/f96355/t96355 test 2025-02-08.md"
FLATTEN file.lists as item
WHERE length(item.children) > 0
AND any(item.children.outlinks)
FLATTEN list(flat(item.children.outlinks)) as candidates
```
## The query with date (as string) checks
```dataview
TABLE WITHOUT ID
item.text as "Text", length(item.children) as "Child count", candidates as "Outlink candidates"
, candidateFiles
, currentDay, aWeekFromNow
, (map(candidateFiles, (c) => c >= currentDay AND c <= aWeekFromNow)) as "candidate checks"
, (map(candidateFiles, (c) => c >= currentDay )) as "after today"
, (map(candidateFiles, (c) => c <= aWeekFromNow )) as "before a week"
FROM "ForumStuff/f96/f96355/t96355 test 2025-02-08.md"
FLATTEN file.lists as item
WHERE length(item.children) > 0
AND any(item.children.outlinks)
FLATTEN list(flat(item.children.outlinks)) as candidates
FLATTEN string(file.day) as currentDay
FLATTEN string(file.day + dur(7 days)) as aWeekFromNow
FLATTEN list(flat(map(candidates, (m) => slice(split(meta(m).path, "/"), -1)))) as candidateFiles
```
## The final query
```dataview
TABLE WITHOUT ID item.text as "Text", relevantChilds.text as "Child text"
FROM "ForumStuff/f96/f96355/t96355 test 2025-02-08.md"
FLATTEN file.lists as item
WHERE length(item.children) > 0
AND any(item.children.outlinks)
FLATTEN list(flat(item.children.outlinks)) as candidates
FLATTEN string(file.day) as currentDay
FLATTEN string(file.day + dur(7 days)) as aWeekFromNow
FLATTEN list(flat(map(candidates, (m) => slice(split(meta(m).path, "/"), -1)))) as candidateFiles
WHERE any(map(candidateFiles, (c) => c >= currentDay AND c <= aWeekFromNow))
FLATTEN list(filter(item.children,
(child) => any(map( child.outlinks, (ol) => slice(split(meta(ol).path, "/"), -1)[0] >= currentDay AND slice(split(meta(ol).path, "/"), -1)[0] <= aWeekFromNow)))) as relevantChilds
```
The final query repeated again:
```dataview
TABLE WITHOUT ID item.text as "Text", relevantChilds.text as "Child text"
FROM "ForumStuff/f96/f96355/t96355 test 2025-02-08.md"
FLATTEN file.lists as item
WHERE length(item.children) > 0
AND any(item.children.outlinks)
FLATTEN list(flat(item.children.outlinks)) as candidates
FLATTEN string(file.day) as currentDay
FLATTEN string(file.day + dur(7 days)) as aWeekFromNow
FLATTEN list(flat(map(candidates, (m) => slice(split(meta(m).path, "/"), -1)))) as candidateFiles
WHERE any(map(candidateFiles, (c) => c >= currentDay AND c <= aWeekFromNow))
FLATTEN list(filter(item.children,
(child) => any(map( child.outlinks, (ol) => slice(split(meta(ol).path, "/"), -1)[0] >= currentDay AND slice(split(meta(ol).path, "/"), -1)[0] <= aWeekFromNow)))) as relevantChilds
```
First of all the FROM "full/file/path/to/date-note.md"
needs to match your daily note name, and I do use file.day
later on to get the date from this file. You could use WHERE file = this.file
instead, at the risk of scanning the full file list of your vault each time you run either of the queries.
The different FLATTEN
’s down the line do the following:
file.lists as item
- Splits up any lists into their seperate item
’s
list(flat(item.children.outlinks)) as candidates
– This hefty line pulls all the links out of any child item to the current item, and stores them into another list (instead of splitting up the query into multiple rows) namely the candidates
list
string(file.day)
and the next – Stores away the currentDay
, and the date aWeekFromNow
- the ugly one
as candidateFiles
– For each of the candidates
, split the path of it into folder parts, and keep only the last part (using slice(..., -1)
. This list is flattened to reduce list levels, and stored as a list in the variable (See detail queries for some variant leading up to this ugly beast)
- Given the variables we’ve built, it’s now a (relatively
) easy WHERE
clause to check if any of the candidates is within the date range
- Another ugly one
as relevantChilds
– If you need to see the line with the date (or whatever), we need to redo the logic to split out the relevant child repeating most of the logic, but now all done in one ugly beast of a statement
So there you have it, a query pulling the appointment line of upcoming dates from your daily pages. In the test file, the final query returns:
Whether this has been explained reasonably, or not, or even if it’s usable in your case, that remains to be seen.