Bases: Access (the number of) incoming links (backlinks) of a file

Use case or problem

While I have already successfully replaced most my dataview-queries with Bases (I personally prefer native functions aka core plugins over community ones), I noticed that I currently cannot access the number of incoming/outgoing links of a file.

This was quite a cool function in dataview where I could sort files by the number of links the file contained via this syntax:

length(file.inlinks) as "in", length(file.outlinks) as "out"

Another cool function in dataview was this code to display all files that link to a note but are not linked backwards:
contains(this.file.inlinks, file.link) AND !contains(this.file.outlinks, file.link)

Proposed solution

I would love to have more information about the file such as the number of in-/outlinks available to us in Bases so that we can create even cooler Tables/Overviews!

12 Likes

Okay, so I managed to find a filter to get all the files that link to the current-file (the base is embedded in), but that are not linked back from the current file:

filters:
  and:
    - linksTo(file.file, this.file.path)
    - not:
        - linksTo(this.file.file, file.file)

Thats already great, but I would still love to find out how many files link to/from the current file :slight_smile:

2 Likes

This code no longer works with Obsidian v1.9.2 - the new working filter is:

filters:
  and:
    - file.hasLink(this.file)
    - not:
        - this.file.hasLink(file.file)

With the new functions/syntax in v1.9.2 it is now also possible to get the number of outgoing links from the current file with this formula:

file.links.length

So now the only thing still missing from my feature request is the ability to access the number of incoming links to the current file.

4 Likes

renamed for clarity

2 Likes

sorry if this is a dumb question - where do I paste this code to make it work in my Base?

All good, don’t worry! There are two ways you can create a base - one is through the “UI” and the other is as a “Code-Block” (similar to how we used Dataview all the time).

The “Code” I provided is copied from a base-codeblock:
ezgif-4533d1057dc8a5

You can also simply paste the lines separately into the filter-UI of a Base by using the advanced formula editor:
ezgif-465b910551270e
Just make sure you select the All are true/None are true-Options to relate the filters:
ezgif-45351a0c747719

Regarding file.links.length - this is just a property-formula:
ezgif-47c7d99fc83571

I hope this helps :blush:

2 Likes

+1

displaying the number of incoming links is one of the last things I can do with dataview but can’t do with bases…

2 Likes

Yes exactly - I have personally already replaced all my Dataview-Queries with Bases and this is the only thing missing for me - sadly I really like to see both the number of incoming and outgoing links to get an overview “how well connected” a note is already :slight_smile:

Hopefully the Obsidian-Team can figure out a good (performant) way to implement this - other than that I really enjoy Bases and love the direction Obsidian is going with them!

3 Likes

+1 for ability to display incoming links count in bases properties

1 Like

Am I missing something of the problem is more fundamental: it is not only impossible right now to show count of incoming links, but to display incoming links in Bases altogether? Intially I thought that file.links displays all links, but now I see that it displays only outgoing links

2 Likes

+1 for this, the actual list of incoming links is far more versatile and is what I would need for my use-case. Not sure about opening an additional feature request, since to me it seems like the most reasonable way to implement this feature request would entail just offering access to the whole list. And without ever having used the dataview plugin, the provided reference makes it look like that is exactly how it is handled there. But it is technically not what was asked for in the initial post.

1 Like

file.backlinks will be introduced in Obsidian 1.9.7. No ETAs.

Be aware that this variable has a performance impact on the table and the table itself is not automatically refreshed in case of changes to the backlinks in the underlying notes. You will have to manually reload the table.

6 Likes

thanks, it works great!

Now I am wondering if it would be possible to add a filtering criteria on the backlinks…

For example I will use the formula file.backlinks.length a lot and I would love to count only the backlinks which are in a specific folder or have a specific property.

Files.backlinks, by default, gives a list of paths to each note. So, you can use filter() before counting the length.

1 Like

Awesome! I just implemented this into my Bases and love it! Thank you and the team for the great work as usual! Highly appreciated!

I tested it. It is slightly more complex than I initially thought, but the basic approach is following

file.backlinks.map(value.asFile().path).filter(value.contains(“Folder”)).length

  1. file.backlinks - gives you the list of all the backlinks
  2. map(value.asFile().path) - convert list of backlinks to the list of paths
  3. filter(value.contains(“Folder”)) - keep only those elements of the list that meet the condition
1 Like

I don’t think you necessarily need the map() here :thinking: …

I mean, you can also coerce value as a File within Filter() :blush: :
(As Filter() will already read and use each backlink (stored/passed as value) to know if it needs to discard it or not)

file.backlinks.filter(value.asFile().path.contains("A Folder")).length

or

file.backlinks.filter(file(value).path.contains("A Folder")).length

… but using map() or not could depend on the use case though, I guess :sweat_smile:

1 Like

Thank you so much, it works great!

though I still have difficulties to understand the inner-working of that filter() function…

Suppose my notes have a property call aliveness. If I want to filter the backlinks from files that have an aliveness over 5 how does it work?

I’ve tried :

  • file.backlinks.filter(file(value).aliveness > 5).length
  • file.backlinks.filter(value.asFile().aliveness > 5).length

but with both I get this error :
“Cannot find “aliveness” on type File”

You would need to access the properties of the note first to be able to dereference/access the desired property :blush: :

file.backlinks.filter(value.asFile().properties.aliveness > 5).length

(assuming aliveness is a number… otherwise, you might need to coerce the “whole thing” (value.asFile().properties.aliveness) into a number first… although, this is just an assumption as I didn’t test any of this :sweat_smile: )

You can only get the implicit properties of a file (file.name, file.ext, etc…) directly from the File object, as in, for example:

file.backlinks.filter(value.asFile().name.StartsWith("C"))

But if you need to access a property stored in Properties, you can do so by using .properties.myProp :blush:

2 Likes

That’s amazing!

with this one I’m starting to like Bases a lot :upside_down_face:

1 Like