Advanced query for tasks not under DOING

Hello,
I’m trying to build a query that finds all "TODO"s that are not childrens (descendants) of “DOING”.
Here is my attempt to build this query:

#+BEGIN_QUERY
{:title "Test"
:query [
	:find (pull ?h [*])
	:in $ %
	:where
	[?h :block/marker ?marker]
	[(contains? #{"TODO"} ?marker)]
	(get-parent ?parent ?h)
	(or-join [?parent]
		(and
			[?parent :block/marker ?pm]
			(not [(contains? #{"DOING"} ?pm)])
		)
	)
]
:rules [
	[(get-parent ?parent ?child)
	 [?child :block/parent ?parent]
	]
	[(get-parent ?parent ?child)
	 [?t :block/parent ?parent]
	 (get-parent ?t ?child)
	]
]
:remove-block-children? false
}
#+END_QUERY

For example, the result should include only marked rows.
Screenshot 2024-04-24 102115

Intuitively, I understand why my request is not working. Maybe some Functions can be used instead of Rules?

Thanks.

Welcome.

  • Try the following:
    #+BEGIN_QUERY
    {:title "Test"
    :query [
    	:find (pull ?h [*])
    	:in $ %
    	:where
    	[?h :block/marker ?marker]
    	[(contains? #{"TODO"} ?marker)]
    	(not
    		(get-parent ?parent ?h)
    		[?parent :block/marker ?pm]
    		[(contains? #{"DOING"} ?pm)]
    	)
    ]
    :rules [
    	[(get-parent ?parent ?child)
    	 [?child :block/parent ?parent]
    	]
    	[(get-parent ?parent ?child)
    	 [?t :block/parent ?parent]
    	 (get-parent ?t ?child)
    	]
    ]
    :remove-block-children? false
    }
    #+END_QUERY
    
  • For better understanding, I would suggest renaming your rule to ancestor, like in this post.
  1. you don’t need an or(-join) at all.
  2. you want to check that each parent is not doing I assume

So we need to change things up a little bit.
We have to first check for all blocks that have a DOING task somewhere in their tree and then exclude those results.

#+BEGIN_QUERY
{:title "Test"
:query [
	:find (pull ?h [*])
	:in $ %
	:where
	[?h :block/marker ?marker]
	[(contains? #{"TODO"} ?marker)]
	(not (check-doing ?h) )
]
:rules [
	[(check-doing ?block)
	 [?block :block/parent ?parent]
     [?parent :block/marker ?pm]
     [(contains? #{"DOING"} ?pm)] 
	]
	[(check-doing ?block)
	 [?block :block/parent ?parent]
	 (check-doing ?parent)
	]
]
:remove-block-children? false
}
#+END_QUERY

Hah! Fun that we took two different approaches :slight_smile:

@SHLEM666 Both work btw :slight_smile:

As usually,

  • I focus on improving the given query.
  • You focus on solving the given problem.
2 Likes

@mentaloid, @Siferiax,

Amazing! I have been trying to find a solution for many hours.
But you did it in minutes.

Thanks a lot!

1 Like