This might currently have some rough edges, I’ll leave what I have so far…
this should match tasks in the given namespace, and tasks under parents with the area tag set to the namespace
… re-reading the original requirement, maybe this instead
#+BEGIN_QUERY
{
:title [:h3 "Project Tasks"]
:inputs ["work"] ; hard coded namespace
; :inputs [:current-page] ; or this if using query on namespace root
:query [
:find (pull ?b [*])
:in $ ?namespace
:where
[?b :block/marker]
(or-join [?namespace ?b]
(and ; does block page belong to namespace?
[?b :block/page ?page]
[?page :block/namespace ?ns]
[?ns :block/original-name ?namespace]
)
(and ; this might not match your original requirement
; match parent block (doesnt have to be a page)
; with area property with namespace
[?b :block/parent ?par]
[?par :block/properties ?props]
[(get ?props :area) ?area]
[(= ?area ?namespace)]
)
(and ; does block page have area property with namespace?
[?b :block/page ?page]
[?page :block/properties ?props]
[(get ?props :area) ?area]
[(= ?area ?namespace)]
)
)
]
;:view :pprint ; debug view if needed
}
#+END_QUERY
Dear @Siferiax , I think this query of yours is the closest. Can you modify it so it doesn’t use the page itself but all aliases? E.g. [[work]]. I want to find all todos with “work” namespaces, tags, and page properties.
r#+BEGIN_QUERY
; see https://discuss.logseq.com/t/advanced-query-that-pulls-all-reference-and-recursive-name-spaces/21275/8
{:title [:h3 "Recursive Namespace + Alias Tasks" ]
:query [:find (pull ?b [*])
:in $ ?inputpage %
:where
[?b :block/marker ?m]
[(contains? #{"NOW" "LATER" "TODO" "DOING"} ?m)]
(or-join [?b ?inputpage]
(and ; Is de page the task is on part of the namespace of the input page?
[?b :block/page ?p]
[?ns :block/name ?inputpage]
(check-ns ?ns ?p)
)
(and ; Does the task refer to the input page in its lineage?
[?p :block/name ?inputpage]
[?b :block/path-refs ?p]
)
(and ; Does the task refer to an alias in it's lineage, either of the input page or a page in its namespace?
(or-join [?p ?inputpage]
(and
[?ns :block/name ?inputpage]
(check-ns ?ns ?p)
)
[?p :block/name ?inputpage]
)
[?p :block/alias ?a]
[?b :block/path-refs ?a]
)
)
]
:result-transform (fn [result]
(let [sorted-result (sort-by (fn [h] (get h :block/marker)) > result)]
(map (fn [m] (assoc m :block/collapsed? true)) sorted-result)))
:group-by-page? yes
:breadcrumb-show? yes
:inputs [:current-page]
:collapsed? false
:rules [
[(check-ns ?ns ?p)
[?p :block/namespace ?ns]
]
[(check-ns ?ns ?p)
[?p :block/namespace ?t]
(check-ns ?ns ?t)
]
]
}
#+END_QUERY
So I eh… reconsidered that entire query, as I was trying to adjust it to add the properties criteria.
If you place this query on the work page (or any other page for that matter). It’ll get all tasks related to the page the query is on.
You can change the input to any lower case page name to get tasks for that specific page, while the query is elsewhere.
Let me know how it goes!
#+BEGIN_QUERY
{:title [:h3 "All tasks related to the current page" ]
:inputs [:current-page]
:query [:find (pull ?b [*])
:in $ ?inputpage %
:where
; get all tasks with a specific status
[?b :block/marker ?m]
[(contains? #{"NOW" "LATER" "TODO" "DOING"} ?m)]
; get the input page, its aliases and its namespaces and their aliases
(or-join [?p ?inputpage]
[?p :block/name ?inputpage] ; ?p is just the input page
(and
[?a :block/name ?inputpage]
[?a :block/alias ?p] ; ?p is the alias of the input page
)
(and
[?ns :block/name ?inputpage]
(check-ns ?ns ?p) ; or ?p is a page in the namespace of the input page
)
(and
[?ns :block/name ?inputpage]
(check-ns ?ns ?a)
[?a :block/alias ?p] ; or ?p is the alias of a page in the namespace of the input page
)
)
; determine if the task belongs to the input page (and related pages)
(or-join [?b ?p ?inputpage]
(and ; Does the page the task is on refer to the input page in its properties?
[?x :block/refs ?p]
[?x :block/pre-block? true]
[?x :block/page ?y]
[?b :block/page ?y]
)
(and ; Is the page the task is on related to the input page?
[?b :block/page ?p]
(not [?p :block/name ?inputpage]) ; we don't need the tasks on the input page itself
)
[?b :block/path-refs ?p] ; Does the task refer to the input page in its lineage?
)
]
:group-by-page? false
:breadcrumb-show? false
:result-transform (fn [result]
(let [sorted-result (sort-by (fn [h] (get h :block/marker)) > result)]
(map (fn [m] (assoc m :block/collapsed? true)) sorted-result))
)
:rules [
[(check-ns ?ns ?p)
[?p :block/namespace ?ns]
]
[(check-ns ?ns ?p)
[?p :block/namespace ?t]
(check-ns ?ns ?t)
]
]
}
#+END_QUERY
I’m really sorry for my ignorance, but how should I modify the query if I want to retrieve tasks from another page? Where should I type the name of the page (in my example: work) I am requesting?
This query is crucial for Logseq project management (at least in my workflow), but I feel this one is generally a gem. It would be even more helpful if it displayed the page and breadcrumbs.
So, I changed these two lines:
The correct syntax is true, not yes.
Also if you want to see them by Page, you’ll need to remove the result-transform, as that will override the group-by-page setting.
This query works well thanks for that.
I have a use case, where I am trying to get away from namespace.
I use journals and not pages to log my items on a daily basis.
Can we extend this query to track tasks that belong to a particular property?
Let’s say I have page [[Team A]] and [[Person B]].
On the [[Person B]] page, I had the tag [[Team A]] at page level
on Today’s journal, I add a TODO [[Person B]] do something
How can I retrieve this tasks if my query is located on [[Team A]] page?
Right now what I use for that is to capture [[Team A/Person B]] using namespace but I’d like to be able to get those blocks from the relation I will add in page properties level but independent of where I collect the task.