• 1 Post
  • 186 Comments
Joined 1 year ago
cake
Cake day: June 27th, 2023

help-circle


  • 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.

    #+BEGIN_QUERY
    {
      :title [:h3 "Author Quotes"]
        :inputs ["Anotherauthor"]          ; could be set to :current-page if included on the Authors page
        :query [
        :find (pull ?b [*]) ?p ?author ?rating ?topics ?pagecount
          :in $ ?authorquery            ; name of the input
          :keys block book author rating topics pagecount 
          :where 
          [?t :block/name "quote"]      ; id of [[Quote]]
          [?b :block/refs ?t ]          ; block referencing [[Quote]]
            [?b :block/page ?p]         ; get id of page
              [?b :block/page ?page]
                [?p :block/properties ?pageprops]
                  [(get ?pageprops :type) ?pagetype]
                    (or [(= ?pagetype "Book")] [(contains? ?pagetype "Book")])         ; is this a Book?
                      [(get ?pageprops :author) ?author]
                    (or [(= ?author ?authorquery)] [(contains? ?author ?authorquery)]) ; is this by input Author? -- comment out line to make all books
                      [(get ?pageprops :topics) ?topics]
                      [(get ?pageprops :pages) ?pagecount]
                      [(get ?pageprops :rating) ?rating]
        ]
          :result-transform (fn [result] 
              (for [row (sort-by :date result)] 
               (let [block-map (get row :block)
                current-properties (:block/properties block-map)
                block-page (:block/page block-map)
                book (:block/original-name block-page)
                authors (:author row)
                updated-properties (assoc current-properties   ; attach book properties to block
                  :booktitle book
                  :topics (:topics row)
                  :pagecount (:pagecount row) 
                  :rating (:rating row)
                  :author authors
                  )]
                (assoc block-map :block/properties updated-properties)
               ) ;end let
              ) ;end for
              ) ;end fn
          ;:view :pprint   ; raw data view for debugging
          :view (fn [rows] [:table   ; uncomment lines below to include author column
              [:thead [:tr 
              [:th "💬Quote"]
              [:th "📖Book"]
    ;          [:th "✏️Author"] 
              ]] [:tbody (for [r rows] [:tr
                [:td [:a 
                    {:href (str "#/page/" (get-in r [:block/uuid]))} 
                    (clojure.string/replace (get-in r [:block/content]) "#Quote" "")
                ]]
                [:td [:a 
                    {:href (str "#/page/" (clojure.string/replace (get-in (get-in r [:block/properties]) [:booktitle]) "/" "%2F"))} 
                    (clojure.string/replace (get-in (get-in r [:block/properties]) [:booktitle]) "Book/" "")
                ]]
    ;            [:td (for [author (get-in (get-in r [:block/properties]) [:author])]
    ;              [:span [:a 
    ;                {:href (str "#/page/" (clojure.string/replace (str author) "/" "%2F"))} 
    ;                (clojure.string/replace (str author) "Author/" ""
    ;                )] 
    ;                (if-not (= author (last (get-in (get-in r [:block/properties]) [:author]))) ", ")]
    ;            )]
              ])]
          ])
    }
    #+END_QUERY
    

  • 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