How to limit the scope of outlinks in dataview

What I’m trying to do

If I write the command ‘length(file.outlinks)’ in DataView, it helps me find the outlinks and inlinks connected to a note. However,
(1) if I want to search for outlinks only within some specific file such as fileA, how can I do that?
(2) If I want to search for outlinks only within notes contained in folders with the name containing ‘schoolbook,’ how can I do that?

I would appreciate it if you could take a moment to help me to solve this question. Thanks.

Hi @sibte8 ,

To list outlinks for a specific file, you can give its full path, including the “.md” extension, in the FROM command, e.g.:

```dataview
LIST file.outlinks
FROM "Topics/grep.md"
```

To filter by folder is a little tricker, but here’s a way to do it using contains():

```dataview
LIST file.outlinks
WHERE contains(file.folder, "Topics")
```

I hope this gets you started. Please let us know how you get on!

Craig

1 Like

Regarding your second question, are you looking for outlinks to notes within the schoolbook folders, or original notes from schoolbook folders?

Thanks. Maybe I’m not say the question clearly.

For example,
question1.md has 10 outlinks.
(1) 7 outlinks from fileA
(2) 3 outlinks from fileB

Table date_created , length(file.outlinks) 

=> The result will show 10 outlinks.
My question is If I just want to show 7 outlinks from fileA. how can I do that?

Thank you.

Hi, I write a example as below to describe the question clearly.

For example,
question2.md has 20 outlinks.
(1) 15 outlinks from file “schoolbook_A”
(2) 3 outlinks from file “schoolbook_B”
(3) 2 outlinks from file “book”

Table date_created , length(file.outlinks) 

=> The result will show 20 outlinks.
My question is If I just want to show 18 outlinks(search the file name contains schoolbook). how can I do that?

Thank you.

OK, if I understand your question correctly, you’d like to filter the list of outlinks so that only outlinks to pages containing “schoolbook” are shown.

It’s a little more complicated, but we can do this using the filter() and meta() functions.

Here’s a similar query, that shows only outlinks where the linked file contains the word “Docker” in its path:

```dataview
TABLE 
	Outlinks,
	length(Outlinks)
FROM "Topics"
FLATTEN list(filter(file.outlinks, (link) => 
	contains(meta(link).path, "Docker"))) as Outlinks
WHERE length(Outlinks) > 0
```

We do a couple of interesting things here:

  • We use FLATTEN to transform the normal file.outlinks into a filtered list containing only the items we want.
  • We use filter() to iterate through the list of links, keeping only the ones we want.
  • We use meta() to extract the path from each link and look for our keyword.
  • Finally, we use WHERE to remove rows that don’t have any outlinks we care about.

To use this query with your data:

  • Change "Topics" to the folder you want to search in, or remove the FROM clause altogether if you want to search all folders.
  • Change "Docker" to "schoolbook" or whatever string you’re looking for in the path.

Hope this helps!

2 Likes

Thank you very much. The code is working. But there are some questions I hope you can help:
(1) FROM “Topics” is the folder I want to search in. => This means search the “TOPICS” folder that match where the “outlinks” at. But I already use the FROM clause to search the question1.md and question2.md and etc .(Just like examples I mention above)
How can I do to use two FROM clause ?
(2)

FLATTEN list(filter(file.outlinks, (link) => 
	contains(meta(link).path, "Docker"))) as Outlinks
WHERE length(Outlinks) > 0

This code can work well. But is it possible to group by the folders?
For example:
schoolbook_A
*
*
*
… total 15 outlinks.
schoolbook_B
*
*
*… total 3 outlinks.


Thanks for your time and your help.

If I understand you right, you’d like to see the list grouped by the linked file, with the list of linking files under each one. We can do that by modifying the query a little, e.g.:

```dataview
LIST rows.file.link
FROM "Topics"
FLATTEN filter(file.outlinks, (link) => 
	contains(meta(link).path, "Docker")) as Outlink
GROUP by Outlink
```

(Again, you’d probably want to change “Topics” to your question folder, and change “Docker” to “schoolbook”.)

This will produce a list with each target file listing the source files under it. In my vault, where I have topics like “Docker” and “Python” pointing to notes like “Hello World…”, it looks like this:

image

I don’t think there’s a way to print the total after the list using Dataview’s query language.

I hope this helps! If you still have questions, and if you feel comfortable doing so, it would be helpful if you posted your full query along with an example of one of the question files and schoolbook files. It would be easier for us to understand what you’re trying to do if we could see where you’re starting.

Thank you for your reply. Your reply is really helpful for me. I also have some questions to ask you for help:

I will give the example as belows,


↑This is the structure of the folder.


↑I use the code as belows you provide. It works well.

Table date_created , file.outlinks, length(file.outlinks) as "all outlinks", Outlinks, length(Outlinks) as "part of outlinks"
from "Physics/physics_book"
FLATTEN list(filter(file.outlinks, (link) =>   contains(meta(link).path, "homework"))) as Outlinks 
WHERE length(Outlinks) > 0
sort length(Outlinks) desc, length(file.outlinks) desc

But I have some complicated question to ask you for help:
(1) I have MOC_phy_chapter1to2.md which has outlinks “phy_chapter1”&“phy_chapter2”
5

I want to put code in the “MOC_phy_chapter1to2.md” file. And the code will shows the result : (only show MOC_phy_chapter1to2.md 's outlinks"phy_chapter1"&“phy_chapter2”)

=> In the same way, when I put code in the “MOC_phy_chapter3to4.md” file, the result will show: (only show MOC_phy_chapter3to4.md 's outlinks"phy_chapter3"&“phy_chapter4”)

(2) Here comes the complex question:
I have MOC_phy.md which has outlinks “MOC_phy_chapter1to2”&“MOC_phy_chapter3to4”
6

When I put code in the "MOC_phy.md"file, the code will show the results as belows,

About (1) & (2), is it possible for dataview to do this? (It means MOC could also has some moc …)

I appreciate for your help. Thanks for your time and your help.

If I understand you correctly, you would one variant of this to actually do a double outlink filter:

  • From current file, check which outlinks are in the same folder
  • From those outlinked file, check which of their outlinks has a folder match to homework

This should indeed be doable, using the same building blocks you’ve already been introduced to. Just replace the file.outlinks in the second part with corresponding stuff from the first output… :slight_smile:

It’s possible some other structure would be better suited for stuff like this, I’m thinking marking some of the files with something (either tags or properties). But it should be doable with the outlink approach too.

It seems like you want to filter the table down so that you see just the source files you’re interested in. I think you can do that with another WHERE clause:

For your multi-chapter topics:

WHERE file.link = [[phy_chapter1]] OR file.link = [[phy_chapter2]]

For your whole-book topic:

WHERE file.link = [[phy_chapter1]] OR file.link = [[phy_chapter2]]
   OR file.link = [[phy_chapter3]] OR file.link = [[phy_chapter4]]

Thanks for your reply.
Is seems that I have to do modify the file.link manully.
Is there a way to do it automatically?
(For example, in MOC_phy_chapter1to2.md, the code will automatically catch the file.link phy_chapter1 and phy_chatpter2.)
(Also, “For your whole-book topic:” ,the code will automatically catch the file.link.)

Thank you verry much.

For your whole book topic, you could use:

WHERE contains(file.name, "phy_chapter")

For the individual chapters, I can’t think of a solution off the top of my head that’s easier than adjusting the WHERE clause. I’ll post again if one occurs to me. :slight_smile:

Coming back to these initial examples from @Craig:

I would like to use LIST file.outlinks together with a filter to show only those outlinks where the respective note has not been created yet (basically the opposite of orphan notes).

What do I need to do? Thanks a lot for your help!

If we have a file, aptly named f73315 non-existing outlinks with this contents:

[[f73315 non-existing outlinks]]
[[NOT f73315 non-existing outlinks]]

```dataview
TABLE WITHOUT ID
  out, meta(out)
WHERE file = this.file
FLATTEN file.outlinks as out
```

We get the output:

And here we can see that the path to the non-existing doesn’t end with .md, which the other one do. This we can use to our advantage in a query like the following naive approach:

```dataview
LIST non_existing_outlinks
WHERE file.outlinks
FLATTEN list(filter(file.outlinks, 
  (o) => !endswith(meta(o).path, ".md") ))
  as non_existing_outlinks
WHERE non_existing_outlinks
```

Sadly this also picks up any non md files, like images, so we need to refine our test a little… Further testing also displayed embeds as a case, to be handled, so maybe this query is a good one?

```dataview
LIST non_existing_outlinks
WHERE file.outlinks
FLATTEN list(filter(file.outlinks, 
  (o) => !meta(o).embed
     AND !regextest("\.[^\.]{2,}$", meta(o).path) ))
  as non_existing_outlinks
WHERE non_existing_outlinks
LIMIT 30
```

If you’ve got a large vault, try increasing that LIMIT in increments, as it might take some time to do this for a larger vault… :slight_smile:

I’m also not sure whether there are other special cases this query doesn’t handle. The cases it do handle however are:

  • The path needs to end with a period followed by at least two non-period characters
  • It needs not to be an embedded link
3 Likes

Thanks a lot @holroy , this works like a charm and using the path characteristics as filter is a clever approach that would have never occurred to me (plus I would not have been able to cook up the dataview expression).

Currently I do not have any non md files in the respective folder, so this poses no problem for now (might change in the future).