FInd nested TODOs

In a fresh Graph I add the following data:

- This is a block that is connected to [[Project A]].
	- Here is a Task that is relevant to this project, but it's not directly tagged with :
		- TODO Write Stuff down
- On the other hand here is a Task that is tagged with the project:
	- TODO Do Stuff 
- TODO And here is a unrelated Task that should not be found

I can’t figure out a query that finds TODO Write Stuff down and TODO Do Stuff - both Tasks are somehow connected to Project A or aren’t they?

Can someone help me with a query? Thanks!

I got you covered in this thread:

If you can’t figure out how to adapt it, let me know!

Thanks! This works fine on the page - how would I change this to work elsewhere? I tried:

#+BEGIN_QUERY
{:title ["Query by page & alias"]
 :query [:find (pull ?b [*])
   :in $ ?page %
   :where
     [?b :block/marker "TODO"]
     [?p :block/name ?page]
     (or-join [?b ?p]
       (check-ref ?p ?b) 
       (and 
          [?p :block/alias ?a]
          (check-ref ?a ?b)
       )
     )
 ]
 :rules [
   [(check-ref ?p ?b)
     [?b :block/refs ?p]
   ]
   [(check-ref ?p ?b)
     [?b :block/parent ?t]
     (check-ref ?p ?t)
   ]
 ]
 :table-view? false
 :inputs ["Project A"]
}
#+END_QUERY

in my Journal, but this didn’t work. Thanks!

@Siferiax not sure if you can help, but I have a very similar issue

I essentially want to make a query like this one:

 - Meeting notes
   - TODO aaaa
   - bbbbb
      - TODO ccccc
      - dddddd
         - TODO eeeee
 - <query here - would return all three TODOs>

Ideally the query wouldn’t need to change depending on the title of the block (that way I can just paste in the query as part of my meeting template and see all the actions at the end of the meeting)
Would love any help you could provide!! :slight_smile:

:block/name is always lower case.
So to accomplish that your input should be "project a".

Edit: otherwise you can use :block/original-name which is the page name as you see it. Whichever option is easier for you.

If you indent the query in it, you can run it based on it’s parent block as input.
So for example:

- parent block title
   - meeting notes
     - stuff
   - query

Or make meeting notes the parent, whatever you prefer.
You can then use this as the query:

#+BEGIN_QUERY
{:title ["Query by page & alias"]
 :query [:find (pull ?b [*])
   :in $ ?parent %
   :where
     [?b :block/marker "TODO"]
     (check-parent ?parent ?b)
 ]
 :rules [
   [(check-parent ?parent ?b)
     [?b :block/parent ?parent]
   ]
   [(check-parent ?parent ?b)
     [?b :block/parent ?t]
     (check-parent ?parent ?t)
   ]
 ]
 :inputs [:parent-block]
}
#+END_QUERY

Disclaimer: I did not test this. I wrote it all on my phone by memory.

3 Likes

Amazing, that worked perfectly - thanks so much, you’re a lifesaver! :slight_smile:
Also incredible you wrote that on your phone by memory!!

1 Like

Since it was featured in Logseq Times, I’ll just add to this post to say I’m a dumdum and there is an attribute for this, making the query A LOT simpler!

This is for the query based on page reference, not the one based on parent blocks.

#+BEGIN_QUERY
{:title ["Query by page & alias"]
 :query [:find (pull ?b [*])
   :in $ ?page
   :where
     [?b :block/marker "TODO"]
     [?p :block/name ?page]
     (or-join [?b ?p]
       [?b :block/path-refs ?p]
       (and 
         [?p :block/alias ?a]
         [?b :block/path-refs ?a]
       )
     )
 ]
 :result-transform :sort-by-priority
 :table-view? false
 :inputs [:query-page] ; alternatively use the lower-case name of a page.
}
#+END_QUERY

This query uses :block/path-refs to find all references in all parent blocks, including the block itself.
As opposed to :block/refs which only looks at the references of the block itself.

1 Like