Advanced query for pages with a tag

I’m trying to make an inbox page for unsorted items. All I would want here is an advanced query for all pages with the #inbox tag. I tried the template in the official docs (see below), however, the query returns 0 results. What is wrong here?

The official docs offer this template (albeit for the “programming” tag):

#+BEGIN_QUERY
{
:query [:find ?name
       :in $ ?tag
       :where
       [?t :block/name ?tag]
       [?p :block/tags ?t]
       [?p :block/name ?name]]
 :inputs ["inbox"]
}
#+END_QUERY

Might be relevant: the tag in question is #inbox, but this is an alias for a page [[:inbox_tray: Inbox]].

This will pull all the pages that have #inbox in their properties definition (tags:: #inbox).

#+BEGIN_QUERY
  {:title [:h6 "Pages tagged #inbox"]
   :query [:find (pull ?h [*])
           :in $ ?target
           :where
           [?h :block/page ?bp]
           [?bp :page/properties ?pp]
           [(get ?pp :tags) ?t]
           [(get ?t ?target)]] 
   :inputs ["inbox"]
   :table-view? false}
#+END_QUERY

This will pull all the blocks that are tagged with #inbox.

#+BEGIN_QUERY
  {:title [:h6 "Blocks tagged #inbox"]
   :query [:find (pull ?h [*])
           :in $ ?target
           :where
           [?p :block/name ?target]
           [?h :block/refs ?p]] 
   :inputs ["inbox"]
   :table-view? false}
 #+END_QUERY

An interesting gotcha with the first query is that [(contains? ?t ?target)] will fail to return true, even if the page has the tag we are looking for. ?t yields a Set and apparently the way to confirm that some tag exists is by going through its hash: we get an exact match or the function call returns nil, which is evaluated as either true or false in Datomic as it seems. (Gotcha Reference)

On a side note: What keeps trowing me off is that I cannot specify a more complex predicate, or fetch condition, for the tag I’m querying. For instance, I would like to match some tag if my ?target is a substring of that tag or if the tag begins with or ends with it.

For example, instead of [(get ?t ?target)], I would expect to somehow be able to match a page property tag with [(some #(str/includes? % ?target) ?t) _] or [(some #(str/starts-with? % ?target) ?t) _].

Perhaps someone else can help out here?

It was back in 2022 and still the docs misinform? Or is it that we’re doing something wrong?

https://docs.logseq.com/#/page/66053e49-889d-4daf-89af-9e7721a7a8ea

#+BEGIN_QUERY
{:title "All pages have a *programming* tag"
 :query [:find ?name
       :in $ ?tag
       :where
       [?t :block/name ?tag]
       [?p :block/tags ?t]
       [?p :block/name ?name]]
 :inputs ["programming"]
 :view (fn [result]
       [:div.flex.flex-col
        (for [page result]
          [:a {:href (str "#/page/" page)} (clojure.string/capitalize page)])])}
#+END_QUERY

So this query refers to some “block/tags” property which doesn’t exist neither on a page nor on a block.

If first block on a page is used to set page properties then why putting #aTag there doesn’t add anything to the page block?

For example, I have a page like:

I’d expect to see my #r/video tag somewhere but page contains just these:

{:block/uuid #uuid "6619c371-2a99-4704-8188-9d6970dccd31",
 :block/journal? false,
 :block/namespace {:db/id 938},
 :block/updated-at 1712965981724,
 :block/created-at 1712958278591,
 :db/id 937,
 :block/name "r/video/bianca - linked knowledge does not work - 2023",
 :block/file {:db/id 1005},
 :block/original-name
 "r/video/Bianca - Linked Knowledge Does Not Work - 2023"}

As you see, there are no properties, nor tags. So how to query pages with a certain tag?

There are both:

  • page properties:
  • tags in them:
    • Should explicitly add a tags:: property.
      • tags:: is a (built-in) property, not part of the (block’s) schema.
    • Should not have TODO in the first block (although could force it in the file).
      • Compare the files:
        • with TODO:
          - TODO
            refs::
            digest::
          
        • with tags and without TODO:
          refs::
          digest::
          tags:: mytag
          
          • Notice the lack of dash - in the first block, indicating that these are page meta-data.
1 Like

That’s it! Not only todo text but any text before the props change that.

Also, there is a lag: after you change the first block, you might need to force re-index to make the actual transition (- itemitem) happen.

Luckily my database is just a few items for now. I should change all the pages.

Thank you!

:block/tags is very much a thing.
And it is specific to the tags:: property in page properties.
From the db schema:

;; for pages
   :block/tags {:db/valueType :db.type/ref
                :db/cardinality :db.cardinality/many}

In Logseq:

It is part of the page data and not the block data.
Query I used:

#+BEGIN_QUERY
{:title "tags"
 :inputs [:query-page]
 :query [:find (pull ?p [*])
  :in $ ?page
  :where
   [?p :block/name ?page]
 ]
 :view (fn [r] [:pre.code (pprint r)])
}
#+END_QUERY

Can see the same using the (Dev) Show page data option:

As for substrings as mentioned earlier in this topic. Can do so with :block/properties-text-values and clojure.string/starts-with?, clojure.string/ends-with? and clojure.string/includes?.

1 Like