I did a lot of tinkering around recently to get an advanced query working for me which ended up being quite tricky to work through. I have Project pages (eg [[12335]]
) and on journal pages I have job note blocks for specific jobs ie #12335 Notes
with a :job
property so the block title can change if needed. There are multiple levels of notes / subnotes / tasks here and I was attempting to do the below query before I learned or-join, but the query was fragile & failing if tasks weren't at a specific indent level. I ended up spending a Sunday afternoon deep diving into this stuff to figure this out.
- As I understand it, the datomic data model is just a HUUGE list of 'datoms' which are super basic [element-id|attribute|value] rows for everything.
- There is some concept of 'unifying' which is a variable that appears twice in a
:where
represents the same value across all clauses. - Something like (or-join) allows you to control this unification to selected sub items.
- My visualization on the query is a graph of conditions
- The :find (?task) element is absolutely required
- There are 'facts' you want to satisfy
[(get ?prop :job) ?job]
[(contains? #{"TODO" "WAITING" "DOING"} ?marker)]
. - ?task β ?prop (through or-join) β ?prop must contain :job with value :current-page
- . β³ ?marker -> must be one of TODO / WAITING / DOING
#+BEGIN_QUERY
{
:title [:h3 "π
Outstanding Tasks"]
:inputs [:current-page]
:query [
:find (pull ?task [*])
:in $ ?job
:where
(or-join [?task ?prop] ; only care that ?task and ?prop are 'unified' with rest of clauses
(and
[?task :block/page ?page]
[?page :block/properties-text-values ?prop] ; does page have :job property?
)
(and
[?task :block/parent ?tp]
[?tp :block/properties-text-values ?prop] ; does task parent have :job property?
)
(and
[?task :block/parent ?tp]
[?tp :block/parent ?tpp]
[?tpp :block/properties-text-values ?prop] ; does task grand-parent contain :job prop?
)
(and
[?task :block/parent ?tp]
[?tp :block/parent ?tpp]
[?tpp :block/parent ?tppp]
[?tppp :block/properties-text-values ?prop] ; does task great-grand-parent contain :job prop?
)
)
[(get ?prop :job) ?job] ; does one-of ?props from above contain :job <%current page%>?
[?task :block/marker ?marker]
[(contains? #{"TODO" "WAITING" "DOING"} ?marker)] ; ?task:block/marker must match one of these
]
:table-view? false
:result-transform (fn [result]
(sort-by (fn [m]
(get m :block/marker)) > result
)
)
:breadcrumb-show? false
:collapsed? false
}
#+END_QUERY
I hope this helps, I'm not entirely sure what/how you want to search on the all quotes page, but there seems to be enough power with advanced queries to get you there.
I tinkered a bit and seem to have found a way, but not sure how powerful the searching needs to be. The rule is overboard as it is showing some techniques for grabbing the data, transforming it and making a custom view. There are extra fields that aren't used, but might be easier to update the :view to include extra fields as needed.