Advanced query for project management (namespace/page-tags, collect tasks from multiple pages)

Hi there,

I have spent quite some time sifting through datalog/query learning resources.

I am doing heavy multi project management on the protocols/detail level with Logseq.
I am still trying to decide if namespaces or tagged pages best serve my need; the idea is as follows: I have hundreds of pages either tagged with page tags like “proj1” or being in a namespace hierarchy like “projects/pro1” and deeper like “projects/proj1/meeting_1”.

Dispersed in these many pages there are dispersed TASKS in different states. For now I only look for “TODO” and “DOING” states.

Solution Draft
Either use the native namespace functionality and show all TASKS on all pages in and below the current namespace in one list; with this list it would be easy to get a feel for all open tasks in this namespace.

Ideally it could also be an advanced query that I can paste on a page of its own, with a title like “All open tasks for proj1”, and the query collects all open tasks from hundreds of pages (which are page-tagged with “proj1” or live in a namespace named “pro1”),

One solution (either page-tags OR namespace) would be a great starting point. I was building on @Siferiax solution in her very helpful collection thread and especially this query:

#+BEGIN_QUERY
 {:title [:b "Tasks on all pages in the namespace proj1"]
  :query [:find (pull ?b [*])
         :where
         (task ?b #{"TODO" "LATER"})
         [?b :block/page ?page]
         [?page :block/journal? false]
         (namespace ?page "projects/proj1")
         (not [?page :block/name "templates"])
       ]
 }
#+END_QUERY

I only got this working for namespaces for now and even they are not searched for alle pages “below” “proj1” namespace.

Would be glad for any pointers in the right direction!

Tom

Welcome. Are you looking for (page-tags ?page #{"proj1"}) ?

Hey, thanks, yes, this would replace the line (namespace ?page "projects/proj1") to filter for page-tags. I couldn’t figure out how to basically OR a pattern matching query in the :where clause - then both should go in there like:

OR ((namespace ?page "projects/proj1") (namespace ?page "projects/proj1")) (which does not work)

the bigger problem is, that the filtering does not seem to work, I get all blocks with TASKS listed, no matter what I try to filter.

An or-clause is written like this: (or patter1 pattern2) , so in your case it should be:

(or (page-tags ?page #{"proj1"}) (namespace ?page "projects/proj1") )

Thanks again, my understanding (and limited experience with advanced queries) is that all expressions in a :where clause are AND connected and writing an OR clause like above does not work here. It works like this in simple queries though. Am I wrong?
At least I get an error if I run this:

#+BEGIN_QUERY
 {:title [:b "Tasks on all pages in the namespace proj1"]
  :query [:find (pull ?b [*])
         :where
         (task ?b #{"TODO" "LATER"})
         [?b :block/page ?page]
         [?page :block/journal? false]
         (or (page-tags ?page #{"proj1"}) (namespace ?page "projects/proj1")
         (not [?page :block/name "templates"])
       ]
 }
#+END_QUERY

=> Result: “Invalid query”

Unfortunately, even little mistakes are not tolerated. Your query is invalid because the or-close is missing its closing parenthesis, i.e. the last character in the line that I provided above.

How stupid, you are right, I didn’t close the parenthesis. With the correct closing it works!
I’ll check for completeness next. Thank you so far.

Just wanted to add my findings:

Datalog query for open tasks in namespace (recursive down):

#+BEGIN_QUERY
 {:title [:b"Namespace search"]
 :query [:find (pull ?b [*])
 :where
  (task ?b #{"TODO" "DOING"})
  [?b :block/page ?p]
  [?p :block/name ?name]
  [(clojure.string/starts-with? ?name "proj1/")]
 ]}
 #+END_QUERY

Datalog query for all open tasks on pages tagged with “proj1”:

#+BEGIN_QUERY
 {:title [:b "Open tasks on all pages tagged proj1"]
  :remove-block-children? false
  :query [:find (pull ?b [*])
         :where
         (task ?b #{"TODO" "DOING"})
         [?b :block/page ?page]
         [?page :block/journal? false]
         (page-tags ?page #{"proj1"})
         (not [?page :block/name "templates"])
       ]
 }
#+END_QUERY

Those work like a charm!
Related discussion: Namespace query retrieve lower levels in the namespace hierarchy