How to create a link to a org-roam search?

Imagine you’re working on a project or research (in org-mode), and you’d like to see your notes that are tagged T or Y, and have links to or from Notes A, K or M. Not a hand-made list, but the updated-for-now list.

Of course, that link runs a search on org-roam.

How do we make a search link like that?

Sorry if it’s obvious and I just didn’t catched it, I’m learning as I go forward. :slight_smile:

Thanks a lot…

Right now you would write your own SQL query for the db. Getting the SQL right isn’t the most fun, but once you have it you’re done.

org-mode helpfully has an elisp: link-type that will run any elisp command you use as its ‘path’, eg. elisp:(find-file "Elisp.org") See here

Running a query is actually pretty easy if you look in a function like org-roam-db--get-titles (do C-h f in emacs), or just look through the source code in org-roam-db.el.

Once you decide on a query you can either link to it or else use a code block in org-mode to write the code and display the results (see here, this is why org-mode is awesome). Something like:

#+BEGIN_SRC elisp
(org-roam-db-query 
  [:select [from] :from links :where (= to $s1)] "path/to/NoteA")

#+END_SRC

That will return all of the filenames to notes that link to Note A. To add more filters (Notes K, M, tags) you can add more SQL or elisp until you get what you want. You can also add things that will output them as file: links to make them functional and navigable if you want (sidenote: I’d be interested if this would work for literally any language that has a SQLite package, if people wanted to rabidly avoid learning elisp).

There should probably be an easier way to do all of this in the future. I would guess it would mostly involve the graph abilities people are working on :slight_smile:

EDIT: I should add that org-roam-db--connected-component also exists, and may suit your needs!

1 Like

I just discovered that emacs Deft can be a big help with this. There’s some integration info in the org-roam manual. Use underscores in Deft in place of spaces in titles (since org-roam makes that conversion for filenames which will show up in the links) and you’ll be good to go.

I use a property to associate metadata with some of my org-roam files. Let’s call the property USERPROP. Is there a way to run a query on USERPROP? I assume that org-roam-db isn’t going to be useful here since it probably is keeping track of only select properties (e.g., filetags, title, id).

I thought Org-roam cached these props in the DB. Did you try this?

I tried without success. BUT… I can count on one hand the number of SQL queries I’ve written.

What I tried:

#+begin_src emacs-lisp
(org-roam-db-query 
  [:select [title] :from nodes :where (= userProp $s1)] "t")
#+end_src

userProp is a string and some of my notes do have its value set to t.

The error I get is: EmacSQL had an unhandled condition: "no such column: userProp"

I have a note with file properties like this:

I can do something like this – the column name you are looking for should be properties.
Note there is (USERPROP . t) in the properties column.

#+begin_src elisp
  (org-roam-db-query
   [:select [title properties]
	    :from nodes
	    :where (= id "2021-04-14T210153")])
#+end_src

#+RESULTS:
| Art History | ((CATEGORY . 2021-04-14T210153__M) (USERPROP . t) (MODIFIED . 2021-08-23T081612) (ID . 2021-04-14T210153) (BLOCKED . ) (FILE . c:/Users/nobiot/evergreen/2021-04-14T210153__M.org) (PRIORITY . B))  |

EDIT: This has worked on my end.
I needed to use ' (raw string).

  (org-roam-db-query
   [:select [title properties]
	    :from nodes
	    :where (like properties '"%USERPROP%")])
1 Like

thanks, @nobiot! I learned a few things from your reply, including how to identify all the fields available in each table. I also see how the output matches the variable org-roam-db--table-schemata.

1 Like

Oh yes :+1:

I thought I would share a query in case it might be useful (or improved upon). The code generates a list of org-roam files formatted as active org-mode links. The listed files satisfy the following query: the title begins with mtg and includes the name of a person. It loops through all hits matching the query. With each hit, it formats the id (first position in list) and associated title (second position). A print function is used to send output to a results drawer. The code inserts the time at which the list is generated. Manually re-executing the code-block (C-c C-c) will re-generate the list.

#+begin_src emacs-lisp :results output drawer
    (print (concat "List as of: " (format-time-string "%a %b %d %H:%M" (current-time))))
    (let ((hits
    	(org-roam-db-query [:select [id title] :from nodes :where (and (like title $s1) (like title $s2))] "mtg%" "%person-name%")
    	))
      (dolist (hit hits)
        (print (concat "[[id:" (car hit) "][" (cadr hit) "]]"))
        )
      )
#+end_src
2 Likes