Help in creating a task query for children blocks under specific parent block

Hello, I am using Logseq to (among other things) process academic papers in my reading list. The way I mark the process is by creating a block in the paper page with a TODO marker and the text “Preparation” and I have under it two child blocks [[Highlighting]] and [[Note structuring]].
image
I want to create a query to find all papers that are e.g. done with the Highlighting but the Note structuring is “TODO” or “DOING”. I am very new to Datalog and I tried to create something on my own, but without any success. Any help would be much appreciated.

1 Like

Something like this:

#+BEGIN_QUERY
{:inputs [:today]
 :query [:find (pull ?b [*])
   :in $ ?today
   :where
     [?highlighting :block/original-name "Highlighting"]
     [?structuring :block/original-name "Note structuring"]
     [?c1 :block/refs ?highlighting]
     [?c1 :block/marker ?marker1]
     [(contains? #{"DONE"} ?marker1)]
     [?c1 :block/parent ?b]
     [?c2 :block/parent ?b]
     [?c2 :block/refs ?structuring]
     [?c2 :block/marker ?marker2]
     [(contains? #{"TODO" or "DOING"} ?marker2)]
 ]
}
#+END_QUERY

I have a quite similar issue where I have a Journal with a section called “Tasks” and one called “Notes”.

Example:

### **Tasks**
   - TODO Task 1
   - TODO Task 2
### **Notes**
   - Note 1
   - Note 2
     - TODO Something to do
   - Note 3
     - TODO Another thing to do

I need a query which only returns the TODOs nested under the “Notes” section but not the ones under “Tasks”. No matter what I try, I either get all TODOs from all Journals or nothing at all.

I tried to rewrite @mentaloid’s example as follows but get nothing in return:

#+BEGIN_QUERY
{ :inputs [:today]
 :query [:find (pull ?b [*])
   :in $ ?today
   :where
     [?notes :block/original-name "Notes"]
     [?c2 :block/parent ?b]
     [?c2 :block/refs ?notes]
     [?c2 :block/marker ?marker2]
     [(contains? #{"TODO" "LATER"} ?marker2)]
 ]
}
#+END_QUERY

I also tried the example from Queries for task management - Customization / Look what I built - Logseq and changed it to show all from today, which works. But now I also have the tasks from the “Tasks” section, which I dont want.

Now I am out of ideas. Anybody who can guide me in the right direction? :slight_smile:

  • Your tasks are nested deeper than one level from their section’s root.
    • That may require recursive lookup (read lower).
      • Could still be avoided if the number of levels under the root is always the same.
  • To filter by section, you need a way to identify the sections. That can be done by either:
    • using content search for "**Notes**"
      • slower, because of string search
      • needs recursive lookup, unless **Notes** is at known level
      • requires no references
    • using a reference, either:
      • in the direct parent or the task itself, e.g. #note
        • avoids recursive lookup
        • requires more references (one per note or task)
      • in the section title, e.g. **[[Notes]]**
        • needs recursive lookup, unless the reference is at known level
        • requires less references (one per section)
        • can also facilitate a fast query of all such sections
  • Which one of the above approaches do you prefer?
    • My personal suggestion is for the last approach, but you may differ.

Ha! Didn’t think I get an answer that fast so I did a bit of back and forth with ChatGPT on that topic. It now works for me with the following query:

#+BEGIN_QUERY
{
  :title [:h4 [:b "From today's notes"]]
  :query [:find (pull ?task [*])
          :in $ ?day
          :where
          [?p :block/journal-day ?day]                         ;; Find today's journal page
          [?section :block/parent ?p]                         ;; Get the parent of the section (the journal page)
          [?section :block/content ?section-content]           
          [(clojure.string/includes? ?section-content "Notes")] ;; Ensure the section is "Notes"
          [?note :block/parent ?section]                       ;; Find blocks under the "Notes" section
          [?task :block/parent ?note]                         ;; Check for tasks under those blocks
          [?task :block/marker ?m]                        ;; Filter for TODO tasks
          (not [(contains? #{"CANCELED"} ?m)])
     ]
  :inputs [:today]
  :table-view? false
  :breadcrumb-show? false
  :result-transform (fn [n] (map (fn [x] (ident x)) n))
}
#+END_QUERY

Thanks anyways for your help.