• Deebster
    link
    fedilink
    English
    arrow-up
    4
    ·
    7 months ago

    I’m no expert in advanced queries, but just to note that you could make things simpler (well, shorter at least) by using a regex to handle all those starts-with lines.

    This selects all pages that don’t start with 0-9 or @:

    #+BEGIN_QUERY
    {
      :title [:h2 "Query Results"]
      :query [
        :find (pull ?p [*])
        :where
        [?p :page/name ?page_name]
        [(re-pattern "^[^0-9@].*") ?regex]
        [(re-matches ?regex ?page_name)]
      ]
    }
    #+END_QUERY
    

    You could also extend the regex to handle the “includes _ or -” bit too:

        [(re-pattern "^[^0-9@_-][^_-]*") ?regex]
    
      • Deebster
        link
        fedilink
        arrow-up
        1
        ·
        7 months ago

        @[email protected] looks good! I am fluent in regex and SQL and I know some Clojure, but these datalog queries are still a bit of mystery to me… that’s the thing I need to visualise!

        • Weiming Hu@mapstodon.spaceOP
          link
          fedilink
          arrow-up
          1
          ·
          7 months ago

          @Deebster I came a different route from data analysis (C, R, Python, Rust) but I’m less familiar with databases. I’m still trying to remind myself that Clojure, datalog, and Datomics are different … And some syntax is not available in Logseq so there is that … 😂

        • autokludge
          link
          fedilink
          English
          arrow-up
          1
          ·
          edit-2
          6 months ago

          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