Lesson 8: Supercharge search with queries

The easiest way to search your Roam database is by using the search bar at the top (shortcut: Cmd-u (macOS)/Ctrl-u (Windows)). Then, using filters you can refine what’s visible on the page.

But what if you want to see results from several pages or want to be very precise about what you’re searching for? That’s when you need queries.

In this lesson, we’ll first dive into boolean logic before digging into how to use it in queries. Queries are one of the most complex things in Roam, but don’t you worry; once you understand boolean logic, writing queries will be a breeze.

Boolean logic

A good start is to first make sure you understand boolean logic. If you’re already familiar with programming logic, you can skip this section (although a refresher is never a bad thing).

Boolean logic is a basic form of algebra, that fully functions with three so-called operators: and, or, not. Each operator is used in combination with one or more arguments, which are values that are searched for. When using these operators and arguments in a statement (a search formula), only one of two results are possible: True or False.

It’s best to explain this using a visual (blue = True, green = False):

Explanation of boolean logic
Source: What is Boolean Logic? by Lotame

In Roam queries, only the blocks that return the result True are shown. By using the operators in combination, you can come to very precise search results. But, to keep things simple, we’ll only focus on the basics now.

Let’s have a look at how the three operators are used in Roam.

Boolean operators in Roam

In Roam, we have access to all three boolean operators to exactly pinpoint blocks. But via the trigger menu (accessed by typing /), only the operators and and or, and the combinations and or and and not are available.

The and operator

When choosing the option Query (and) in the trigger menu, the following statement appears:

{{[[query]]: {and: [[ex-A]] [[ex-B]]}}}

Automatically, we get two placeholder arguments: ex-A and ex-B. Replace these with any page name in Roam, and add as many as you like.

Using the and operator, only the blocks that mention all of the arguments are shown.

The or operator

When choosing the option Query (or) in the trigger menu, the following statement appears:

{{[[query]]: {or: [[ex-B]] [[ex-C]]}}}

Automatically, we get two placeholder arguments: ex-B and ex-C. Replace these with any page name in Roam, and add as many as you like.

Using the or operator, the blocks that mention any of the arguments are shown.

The and or combination

When choosing the option Query (and or) in the trigger menu, the following statement appears:

{{[[query]]: {and: [[ex-A]] {or: [[ex-B]] [[ex-C]]}}}}

Automatically, we get three placeholder arguments: ex-A, ex-B, and ex-C. This statement is a bit more complex than the previous ones, as it contains an or operator nested within the and operator.

What this does is first search for all mentions of either ex-B or ex-C. Then, the result of that search is automatically fed into the and operator, which searches for all mentions of ex-A and the result of the nested search.

The and not combination

When choosing the option Query (and not) in the trigger menu, the following statement appears:

{{[[query]]: {and: [[ex-A]] {not: [[ex-B]]]}}}}

Automatically, we get two placeholder arguments: ex-B and ex-C. Again, you can add as many arguments to each operator as you want.

What this statement does is search for all blocks that mention ex-A but don’t mention ex-B.

Extra: The between operator

As often, there’s also an undocumented operator in Roam. While this is strictly not a boolean operator, it makes searching within date ranges much easier.

You can’t access this operator via the trigger menu, that’s why we give you an example here:

{{[[query]]: {and: [[ex-A]] {between: [[January 1st, 2020]] [[October 1st, 2020]]}}}}

As you can see, this statement contains a nested between operator that date two dates as arguments.

What it does is look for all mentions of ex-A on the Daily Note pages between January 1st, 2020 and October 1st, 2020. It does not return all blocks that were created between those dates.

Queries are like a saved search

Why would you go through the trouble of writing queries when you can search and filter? First, queries allow for much more precise searching. Second, queries are like a saved search.

Every time a block meets the requirements to be included in a query, it automatically appears in the query results. That’s the reason many Roam users write queries to handle their TODO lists or use it to build pipelines based on statuses.

Exercise

Do you find searching for the same terms over and over? Create a page where you group queries for easy overview.

If you already use Roam’s template functionality, consider adding a query block that pulls in all your TODOs with a specific tag.

Additional resources

If you want to dig deeper into the world of Roam queries, I recommend you watch the following videos.

Rob Haisfield explains how queries work, shows how to nest them, and gives a demo of how get exactly the results you want:

Ben Kaluza shows how he uses queries to automatically move blocks in his project and task management workflows:

Was this helpful?