Blocks belonging to a list of pages in the tags property of the current page

I create a “project” page that is linked to a series of “other” pages by listing them in the tags:: property of the “project” page. I tag some blocks on those “other” pages with #Issue.

I would like a query that lives on the “project” page that returns all the blocks tagged with #Issue that live on the pages listed in the tags: property of the tags:: “project” page. I can write a query that explicitly lists the pages from the tags:: property, but there must be a way to dynamically include that tags:: list?

1 Like

Welcome. Try this:

#+BEGIN_QUERY
{:query [:find (pull ?b [*])
   :in $ ?current
   :where
     [?issue :block/name "issue"]
     [?project :block/name ?current]
     [?b :block/refs ?issue]
     [?project :block/tags ?p]
     (or
       [?b :block/page ?p]
       [?b :block/path-refs ?p]
     )
 ]
 :inputs [:query-page]
}
#+END_QUERY

I didn’t explain myself clearly. In my description the page I referred to as “project” is the current page on which the query will be stored. It could have any name.

Its properties would look like:

etype:: Project
estatus:: Active
tags:: Page1, Page2,

I’m looking for any blocks on Page1 and Page2 etc. that contain #Issue
My template for pages of type Project will contain the query

Check Have current-page trigger only when template is applied. I have updated my previous answer accordingly:

  • Add :inputs [:query-page]
    • or :inputs [:current-page] if needed
  • Add e.g. :in $ ?current
  • Replace [?project :block/name "project"] with e.g. [?project :block/name ?current]

I altered the query to:

#+BEGIN_QUERY
{:query [:find (pull ?b [*])
   :in $ ?current
   :where
     [?issue :block/name "issue"]
     [?project :block/name ?current]
     [?b :block/refs ?issue]
     [?project :block/tags ?p]
     [?b :block/page ?p]
 ]
:inputs [:query-page]
}
#+END_QUERY

Not returning anything.

But this does:

#+BEGIN_QUERY
{:title [:h3 "Issues out there"]
:query (and (or [[Page1]] [[Page2]] )  [[Issue]]   ) }
#+END_QUERY

I’m trying to get the equivalent of the explicit (or [[Page1]] [[Page2]]) to be built from the list found in tags:: on the query-page

I also tried putting [[]] around Page1 and Page2 in the tags::
and I tried “Issue” and “issue”

How does ?p in

[?project :block/tags ?p]
[?b :block/page ?p]

get values?

To me both queries return the same results. I would suggest that you create a new graph with minimal simple blocks and pages, and start building the query one step at a time, ensuring that each step returns the expected results, until you reach the step that this breaks. For example, the following query should return the tags:

#+BEGIN_QUERY
{:query [:find ?tag
   :where
     [?project :block/name "project"]
     [?project :block/tags ?p]
     [?p :block/name ?tag]
 ]
}
#+END_QUERY

I simplified everything and it works for me too. I simplified my description too much. The pages are actually in a namespace hierarchy. And that is the problem.

So:

ProjectPage/Page1
ProjectPage/Page2

with the query on ProjectPage. Its properties:

etype:: Project
estatus:: Active
tags:: ProjectPage/Page1, ProjectPage/Page2, …

I changed my (working) simplified setup to put Page1 in a namespace and then only Page2 worked. Is there a solution? Your attention is much appreciated!!!

I cannot reproduce the problem so far.

I don’t see how namespaces could affect the query.

  • Have you properly changed all mentions of Page1?
    • Did you re-index afterwards?
  • Have you tried with a new graph, this time using namespaces since the beginning?

Re-indexing has fixed the namespace problem, sorry about that. The query is not finding journal entries. Do those have to be allowed for separately?

What do you mean? Do you set journal names as values in property tags:: ? Please keep providing examples for us to reproduce and facilitate the communication.

Sorry for the vagueness. Can the query be enhanced to also find blocks on Journal pages with the #Issue tag for the pages in the tags:: list on the query-page ?

So, a block on a journal page could look like:

#ProjectPage/Page1
This a description of a #Issue

or

This is an #Issue for #ProjectPage/Page1

I had thought the journal pages would automatically be in scope but I guess this combination has to be found solely at the block level?

Advanced queries are on purpose the opposite of automatic, so as they can be precisely tailored. Therefore, should explicitly add a separate case, replacing [?b :block/page ?p] with:

     (or
       [?b :block/page ?p]
       [?b :block/refs ?p]
     )

No joy with:

#+BEGIN_QUERY
{:query [:find (pull ?b [*])
   :in $ ?current
   :where
     [?issue :block/name "issue"]
     [?project :block/name ?current]
     [?b :block/refs ?issue]
     [?project :block/tags ?p]
      (or [?b :block/page ?p]
       [?b :block/refs ?p]
     )
 ]
:inputs [:query-page]
}
#+END_QUERY

The Journal entries look like:

  • #Site0/Page1
    • This is a daily block not tagged
    • This is a daily block tagged as an #Issue
  • #Site0/Page2
    • This is a daily block tagged as an #Issue

I see that if I put both the page and the Issue tag in the same block then it works. When I notetake I’ll indent all the notes for project as blocks under a line with the projects page as a tag or as a link.

This works using the simple query with the page links [[Site0/Page1]], [[Site0/Page2]] explicitly defined. Is getting that list of page links in from the tags:: just not possible? While it works for me, perhaps I’m not structuring the notes the way logseq is designed for.

Just replace [?b :block/refs ?p] with [?b :block/path-refs ?p]

That’s done it. Thank-you!!

I really appreciate your patience with this. It’s made maintaining my workflow much easier.

Now, I can puzzle out what each of the steps within the query do.