Dataview query that filters inlinks

Things I have tried

This query lists all files with no inlinks. But I only want the files with no inlinks that match certain criteria.

LIST
WHERE sub = [[Goal]]
AND length(file.inlinks) = 0

I’ve read elsewhere in this forum that you probably can’t filter inlinks. I got more optimistic when blacksmithju wrote about any operations, but the reference document for any is challenging without examples.

What I’m trying to do

My files:

#Goal X
sub:: [[Goal]]

#Priority 1
sub:: [[Priority]]
goal:: [[Goal X]]

#Some other note that may help me with Goal X
sub:: [[Note]]
goal:: [[Goal X]]

I want to find all the goals that do not have a priority assigned to them yet. .i.e. a query that selectively acts on priority notes that link to a goal note. If there are none, then I know I have to give it a priority note.

These do not work:

LIST
WHERE sub = [[Goal]]
AND any(file.inlinks, contains(file.name, "🔝"))
LIST
WHERE sub = [[Goal]]
AND any(file.inlinks, startswith(file.name, "🔝"))

(My priority files happen to start with an emoji “:top:”)

Can anyone help me out?

Hi.

I have some difficulty to understand your goal (maybe my bad, because my english isn’t the best…).

So. If we focus on note [[Goal]], you want to query all the notes with link to “Goal” note (i.e., inlinks to “Goal”) and then filter these inlinks to only ones that don’t have an outlink to [[Prority]]note?

For example:

  • “Goal” note has as inlinks fileA, fileB and fileC
  • fileC has a (out)link to “Priority” note but others two files not
  • you want fileA and fileC as query result

(From your post I just don’t understand what you consider inlinks and outlinks. Because if you write WHERE sub = [[Goal]] this means «all the files with a link to [[Goal]] in the field sub» - if sub:: [[Goal]] this means too an outlink from this file and an inlink to “Goal” file. Another doubt is if the link to [[Priority]] is assigned to any field - sub?, the same field where you assigned a link to [[Goal]]? Last question: your links [[Goal]], [[Priority]], … exists as markdown files?)

My English is also not the best, so I think I have not explained myself the best. Thank you for your patience.

For better or worse, I do not use tags. Instead I give a note a dataview key called “sub” (Like Reddit). So, sub:: Goal for goals, sub:: Priority for priorities.

Here is how I query for goals (in this case active goals):

TABLE WITHOUT ID link(file.link, file.title) AS "active goal", length(file.inlinks) as "total priorities"
FROM !"_templates"
WHERE sub = [[Goal]] 
AND completed = [[Active]]

If the “length(file.inlinks) = 0”, that is my signal to write a priority note for it, at which point “length(file.inlinks) = 1”

The problem is I have other supporting files that link to the goals notes (they have key sub:: [[note]]. They are also inlinks to the goals note. I want to exclude them from the query.

If I may rewrite your example:

  • “Goal” note has inlinks from every note labelled sub:: [[Goal]]. Admittedly confusing but I don’t think relevant to this scenario.
  • “Goal X” note has inlink PriorityX. Yes! The query works! No Priority note needed.
  • “Goal Y” note has no inlinks. Yes! The query works! I write Priority note
  • “Goal Z” note has inlinks fileA, fileB, fileC. Oops! The query will not tell me to create a priority note this goal because “length(file.inlinks) = 3”

I think the any(array) operator may work. I just don’t understand the examples from blacksmithgu and Dataview Reference

.…if you write WHERE sub = [[Goal]] this means «all the files with a link to [[Goal]] in the field sub» - if sub:: [[Goal]] this means too an outlink from this file and an inlink to “Goal” file.

Yes. This is intentional. Goal.md is simply a file with a query to inlinks, so I can see a list of all goals.

Another doubt is if the link to [[Priority]] is assigned to any field - sub?, the same field where you assigned a link to [[Goal]]?

No. sub:: Priority only in note that has a priority statement. sub:: Goal only in a note that has a goal statement. sub:: note only in a general note, which make up the vast majority of my vault.

Last question: your links [[Goal]], [[Priority]], … exists as markdown files?)

Yes

Hi. In a fast answer (sorry, but I’m a little busy now), for test purposes, replace your first line in query with this:

TABLE WITHOUT ID link(file.link, file.title) AS "active goal", file.inlinks, length(file.inlinks) as "total inlinks", file.inlinks.sub, filter(file.inlinks.sub, (s) => contains(s, [[Priority]])) AS "priorities", length(filter(file.inlinks.sub, (s) => contains(s, [[Priority]]))) AS "total priorities"
FROM ...

Check and compare each field. The last column gives you what you want?

Yes, it is having the desired effect. Thank you @mnvwvnm

So, it is the filter function to be used. I find this query takes a long time to load (>30s). Is it possible it is straining too much my vault?

About the time to load… The question is:

  • How many notes dataview need to check to apply the desired filter?
  • The main command to filter the notes to check is the command FROM, i.e., limiting the source (“what pages will initially be collected and passed onto the other commands for further filtering”).
  • There is any possibility to reduce the source by folder(s)?
1 Like

Now I try to build on your query to simply list all the goals and their associated priorities. But file.links column still lists all inlinks, not just the ones from [[Priority]]. The other columns display as expected. Any suggestions how to exclude other inlinks?

TABLE file.inlinks, filter(file.inlinks.sub, (s) => contains(s, [[Priority]])) AS priority, length(filter(file.inlinks.sub, (s) => contains(s, [[Priority]]))) AS Σpriorities
WHERE sub = [[Goal]] 
AND filter(file.inlinks.sub, (s) => contains(s, [[Priority]]))
AND completed = [[Active]]
FROM…

I’m confused again. Now you want a query to list ONLY the goals with [[Priority]] assigned?

TABLE file.inlinks, filter(file.inlinks.sub, (s) => contains(s, [[Priority]])) AS priority, length(filter(file.inlinks.sub, (s) => contains(s, [[Priority]]))) AS Σpriorities
WHERE sub = [[Goal]] AND contains(file.inlinks.sub, [[Priority]])

You mean file.inlinks?

If about file.inlinks, replace first part with this:

TABLE filter(file.inlinks, (i) => i.sub = [[Priority]]) AS inlinks, ...
2 Likes

Thank you! There are not many DQL filter() examples that I have seen, so this is very useful.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.