Make block and page references consistent (`path-refs` in advanced queries)

Please make advanced queries for block and page references behave the same with regards to :block/path-refs.
The idea is to to gradually make blocks and pages consistent, so that they can be used interchangeably in queries.

More details

Let’s take an example - find all blocks that have links my page:

# test case.md
- b1 of test case with link to [[my page]]
# my page.md
- b1 of my page
- b2 of my page
{{query [[my page]] }}

would be able to find all three blocks. This is great, because we asked for blocks that link to my page, but also can find content inside my page itself! More technically, contained blocks of my page inherit a link reference to this page, which is added in :block/path-refs.

OK, let’s try to add a block reference.

# my page.md
- my block
  id:: 1234
  - child 1

and reference it somewhere:

# test case.md
- ((1234))

Using advanced queries here, as simple queries (TMK) have no way to query blocks:

{
:query [:find (pull ?b [*])
    :where
        [?br :block/uuid #uuid "1234"]
        [?b :block/path-refs ?br]
]
}

In contrast, this will only find the “outside” block link in test case, not child 1 (or other child blocks of my block).

In my book, these two cases would be equivalent, but currently are treated not consistently.
I’d image, this decision been driven by performance reasons - if so, might this be solved by a more database-driven Logseq approach?

There is a workaround for the block case query. But I think a more uniform approach would be beneficial, especially for people seeking more block-level experience. Thanks!

Can you please share the workaround you are referring to?
Will it help with querying child blocks with to do tags that have no block refernce tags but its parent block has tags with block references?

If it’s super important to you, I’d need to search in second brain. But never used it in practice, as too complicated for daily needs.

Thanks for getting back. It would benefit me if you have time as I have several use cases that I can repurpose it for.

Hi @Jc12 again and sorry for the late reply.
I have stored one example in my notes regarding this topic, hopefully this will be useful for your own case:

#+BEGIN_QUERY
{
:title ["Given a block UUID, return all blocks that reference this block and additionally have a page link to 'hello'. Also search through given block itself for references of 'hello' (implementation of proper path-refs for blocks)"]
:query [
:find (pull ?bout [*])
:in $ ?uuid %
:where 
    [?b :block/uuid ?uuid]
    (or
        [?bout :block/path-refs ?b]
        (with-children-blocks ?b ?bout)
    )
    [?p :block/name "hello"]
    [?bout :block/path-refs ?p]
]
:inputs [#uuid "<your uuid string>"]
:rules [
  [(with-children-blocks ?bin ?bout) 
      [(identity ?bin) ?bout]]
  [(with-children-blocks ?bin ?bout)
      [?bchild :block/parent ?bin] 
      (with-children-blocks ?bchild ?bout)]
]
}
#+END_QUERY

Idea is to grab all children blocks of input block in a recursive rule. This worked at the time of testing, if I recall correctly. Unfortunately I am way out of the topic.

thank you Venture-comp

1 Like