Namespace query retrieve lower levels in the namespace hierarchy

Namespaces in queries for tasks, for example {{query (and (namespace [[Golf]]) (task TODO))}} not picking up lower levels in the hierarchy.

If I have TODOs in Golf/Level1 page then the query picks up the tasks without any problem. However if I put a task in Golf/Level1/Level2 page, the query doesn’t find the TODO. I’d like to find tasks at any level in the hierarchy.

Hierarchical pages are a great feature, but there is a bit of work to be done. When I search for “A/B” when there are lots of pages with the name “A/B/X” (A and B are single pages, X refers to multiple pages), often the search does not find “A/B”. this is not quite the same as your Feature Request, but related, I think.

If you have a namespace like this: [[myspace/aaa/bbb]] with tasks on page aaaa and bbbb

Then this will find the tasks on page aaaa

 #+BEGIN_QUERY
 {:title [:b "my title"]
 :query [:find (pull ?b [*])
 :where
 [task ?b #{"TODO"}]
 [?b :block/page ?p]
 (namespace ?p "myspace")
 ]}
 #+END_QUERY

To also find tasks on page bbbb, use:

 #+BEGIN_QUERY
 {:title [:b"Namespace search"]
 :query [:find (pull ?b [*])
 :where
  (task ?b #{"TODO" "DOING"})
  [?b :block/page ?p]
  [?p :block/name ?name]
  [(clojure.string/starts-with? ?name "myspace/")]
 ]}
 #+END_QUERY

As alternatives to [(clojure.string/starts-with? ?name "myspace/")] there are also:

  • clojure.string/ends-with?
  • clojure.string/includes?

With combinations of these you can find any namespaced tasks you need.

3 Likes

Those queries work perfectly for me. Thank you

@Alex_QWxleA I tried your approach with block properties, but I am getting a “Block Render Error”.
Do you see anything wrong with this query?

#+BEGIN_QUERY
{ :query [ 
       :find (pull ?b [*]) ; 
       :where
           [?b :block/properties ?properties]
           [(get ?properties :type) ?type]        
           [(clojure.string/starts-with? ?type "content/")]
       ] 
} 
#+END_QUERY

I get no block render error on Logseq 0.8.2 on Mac and Android

Checkout Logseq Query Builder v0.01 to see examples with block property queries

I get no block render error on Logseq 0.8.2 on Mac and Android

Yes, exactly what I get too! Do you see what I could be doing wrong that would cause this?

Checkout Logseq Query Builder v0.01 to see examples with block property queries

I did check your query builder (really great stuff btw), however, it has no example of querying by a property substring, which is what I am trying to do here in order to get all lower levels of the namespace which is used as a property.

Cheers

So are you using the block property :type to hold namespace-like levels rather than using page names?

So are you using the block property :type to hold namespace-like levels rather than using page names?

Yes, take this example:

### Zettelkasten note-taking with Logseq: A simple introduction (Part 1)
type:: [[content/video]] 
author:: [[Dario da Silva]] 
source:: https://youtu.be/MEZc2nW09Ns
tags:: Zettelkasten, Second Brain

Whereas other options of type are [[content/article]], [[content/book]], [[content/course]], [[content/tweet]], etc.
Now what if I want a list of all type [[content/*]]?

I thought the query I created using clojure.string/starts-with? would work, but it is giving me that block render error.

1 Like

I see that you are using a page link as the value in the property rather than just the value without the [[ and ]] wrapper. So I thought what if I remove the [[ and ]] … will this work. Unfortunately I was only able to test for the full value eg content/video with [(= ?type “content/video”)] but strangely, as you say, using the starts-with? does not work. I think the underlying problem here might be that datalog or clojure are not treating ?type as a true string but as an item in a clojure set. I think you need to ask the gurus on the Logseq Discord as I’m struggling to find an answer. Let me know ho you go. In the meantime I’ll keep digging.

1 Like

I’ve raised a question on Discord, hopefully we’ll get an answer from one of the datalog gurus.
Discord

1 Like

I still am not sure why the [(clojure.string/starts-with? ?type "content/")] breaks here, but I did manage to solve my issue with another solution. I got a solution from Discord (here) which consists of the following:

#+BEGIN_QUERY
{
 :query [:find (pull ?b [*])
       :where
           [?b :block/properties ?properties]
           [(get ?properties :type) ?type] ; get type property
           ; find page (nsp) referred to by property "type" 
           [?nsp :block/journal? false] ; get any block that are journal and save it to ?nsp
           [?nsp :block/original-name ?nsp-n] ;  get block name from ?nsp
           [(contains? ?type ?nsp-n)] ; filter ?nsp name only name are from property
           ; filter by the first part of the namespace
           [?nsp :block/namespace ?ns]
           [?ns :block/original-name "content"]
     ]
} 
#+END_QUERY
1 Like