How to find all tasks under blocks tagged with project namespaces?

In my daily notes, I jot down notes and tasks under blocks tagged with the project name, in this format:

image

I need help formulating the following queries please:

  1. Find all tasks under blocks tagged with [[Projects/Personal/test2]]
  2. Find all tasks under blocks tagged with [[Projects/Personal/…]]
  3. Find all tasks under blocks tagged with [[Projects/…/…]]

Thanks in advance to anybody who can help! :pray:

1 Like

Here’s your query.
Important notes :block/name is the lower-case name of a page. When you use namespaces, it will get everything referencing the namespace regardless of what level of the namespace.
So project gets Project, but also Project/Personal.
project/personal will get Project/Personal and also Project/Personal/test, but not Project.
See the screenshot I added :slight_smile:

#+BEGIN_QUERY
{:title "🔨 Project TODO"
  :query [:find (pull ?b [*])
          :where
          [?p :block/name "project"]
          [?par :block/refs ?p]
          [?b :block/parent ?par]
          [?b :block/marker ?marker]
          [(contains? #{"TODO"} ?marker)]
  ]
}
#+END_QUERY

And a variation

#+BEGIN_QUERY
{:title "🔨 Project TODO"
  :query [:find (pull ?b [*])
          :where
          [?p :block/name "project/personal"]
          [?par :block/refs ?p]
          [?b :block/parent ?par]
          [?b :block/marker ?marker]
          [(contains? #{"TODO"} ?marker)]
  ]
}
#+END_QUERY

1 Like

Thank you so much — this is super helpful! :blush::pray: I guess I need to start learning advanced queries much better to beef up my workflow.

One thing I forgot to mention in my original workflow - sometimes I tag the task directly rather than nesting under a tag (see last meeting example in this screenshot). Any chance you can help me modify the original query to get these tasks as well? (Your query currently returns the tasks from the first two meetings, but does not return tasks from the third meeting in this screenshot)

image

Change the line
[?b :block/parent ?par]
To

(or [?b :block/parent ?par]
     [?b :block/refs ?p])

Works like a charm - you are Amazing!!!

1 Like

Hi there, i am new to advanced queries in Logseq.
I found your hint for queries in namespaces and tried to apply it to my own example, but get no results.

This is my example. I try to get a query that shows the two tasks in the sub-pages of the namespace.

This is my query. I only changed the String “TODO” to “LATER”.
002

Can you give me an advice, what I am missing?
Thanks in advance.

This goes from relatively simple to relatively complex pretty fast.
First of :block/refs doesn’t get what you need.
Also you want the block on the page and not the parent of the block, though in this case that is the same, but if your task is under a parent block you won’t retrieve it.
Next getting a namespace is only 1 level deep, and here’s where the complexity comes from.
I’m going to assume you don’t want that to be static :face_with_hand_over_mouth:
So I use rules to create a recursive search to find all pages under project, no matter their dept.
Here’s the query I created:

#+BEGIN_QUERY
{:title "Find Sub-Tasks"
 :query [:find (pull ?b [*])
   :in $ %
   :where
     [?ns :block/name "project"]
     (check-ns ?ns ?p)
     [?b :block/page ?p]
     [?b :block/marker ?marker]
     [(contains? #{"LATER"} ?marker)]
 ]
 :rules [
   [(check-ns ?ns ?page)
     [?page :block/namespace ?ns]
   ]
   [(check-ns ?ns ?page)
     [?page :block/namespace ?t]
     (check-ns ?ns ?t)
   ]
 ]
}
#+END_QUERY
2 Likes

Perfect! It works!
Now I really can draw the Power of Logseq for my purposes.
Thanks, mighty wizard.
I do not understand the magic yet, but can use it and am eager to learn more.

1 Like

When i put “project” (or the final target string) in lowercase letters, it works as intentioned.
Next i’ll try to filter on tasks with priority “A”.
Maybe i can do it without help from a magician.

Dear Siferiax, I do not want to be greedy but could you extend your helpful Query so that it Filters Namespace + Tasks + Priority “A”
As a beginner i still struggle a little with learning datalog.

Yes. :block/name is always lowercase. I forgot to mention, I generally add that for clarity!
Pages have 2 names, one is lowercase and stored in the attribute :block/name and the other is their original name case stored in :block/original-name.
I generally use :block/name so we don’t have to think how exactly we wrote the name of a page :slight_smile:

For filtering priority we have the attribute :block/priority
So we will need to add the line: [?b :block/priority "A"] to the query.
Alternatively we can do this the same way as we did for the task itself.

[?b :block/priority ?prio]
[(contains? #{"A" "B"} ?prio)]

In this case finding both A and B priority tasks. Just to illustrate how you can use multiple values for the contains? function.

Complete query for clarity:

#+BEGIN_QUERY
{:title "Find Sub-Tasks"
 :query [:find (pull ?b [*])
   :in $ %
   :where
     [?ns :block/name "project"]
     (check-ns ?ns ?p)
     [?b :block/page ?p]
     [?b :block/marker ?marker]
     [(contains? #{"LATER"} ?marker)]
     [?b :block/priority ?prio]
     [(contains? #{"A"} ?prio)]
 ]
 :rules [
   [(check-ns ?ns ?page)
     [?page :block/namespace ?ns]
   ]
   [(check-ns ?ns ?page)
     [?page :block/namespace ?t]
     (check-ns ?ns ?t)
   ]
 ]
}
#+END_QUERY
1 Like

Hi there @Siferiax , many thanks for the solution… its nearly perfect.
If you allow one last question:
Sometimes i would also note some tasks in the root layer of a namespace (“project/…”).
Is it possible to include these tasks with priority into the query results?

Best regards, already a fan… :slight_smile:

Someone should develop a GPT based AI that can transform natural language queries into advanced logseq queries! I wonder if anyone is thinking about this?

1 Like

Hi there,
i already found the great Query-Builder-Tool from adxsoft

but couldn’t figure out how to build a recursive query for the namespaces like the one @Siferiax provided. Maybe its just a matter of time learning the nuances of datalog.
For now the hints from Siferiax provides a very powerful solution for project management in Logseq.

There seems to be another question/solution that tackles the problem of queries in hierarchies.

Yes, definitely!
Change [?b :block/page ?p] to:

(or
  [?b :block/page ?ns]
  [?b :block/page ?p]
)
1 Like

Yeah that solution does basically the same thing as my solution :wink:

Thanks mighty Query-Wizard! :smiley:

So this query you suggested works

#+BEGIN_QUERY
{:title "🔨 All projects"
  :query [:find (pull ?b [*])
          :where
          [?p :block/name "projects"]
          [?par :block/refs ?p]
          (or [?b :block/parent ?par]
     [?b :block/refs ?p])
          [?b :block/marker ?marker]
          [(contains? #{"TODO"} ?marker)]
  ]
:collapsed? true
}
#+END_QUERY

But now I’m trying the following as the inverse - i.e. find all todos that don’t have any project tags, but it’s finding no results (despite the fact that I’ve created some test todos without project tags). Any idea how I can fix this? Thanks very much in advance! :slight_smile:

#+BEGIN_QUERY
{:title "🔨 Inbox"
  :query [:find (pull ?b [*])
          :where
          [?p :block/name "projects"]
          [?par :block/refs ?p]
          (not (or [?b :block/parent ?par]
     [?b :block/refs ?p]))
          [?b :block/marker ?marker]
          [(contains? #{"TODO"} ?marker)]
  ]
:collapsed? false
}
#+END_QUERY