Query to find orphan blocks?

Is it possible to have a query which will pick up blocks where the block (and any of its nested children) do not have any page / tag reference (in any direction)?

Motivation is that I (as many others) write in Journals window by default, and it’s easy for some notes to slip through the cracks. With this query, it would be easy to find them.

I’ve seen somebody suggested using something like #fleeting when working with such block (when you’re not sure where they’d go), but with such a query, one wouldn’t even need to remember to tag it :slight_smile:

Something like this:

#+BEGIN_QUERY
{
 :query [:find (pull ?block [*])
 :in $ %
 :where
   [?block :block/page ?page]
   (not [?block :block/refs])
   (not
     (descendant ?d ?block)
     [?d :block/refs]
   )
 ]
 :inputs [
   [
     [
       [descendant ?d ?b]
       [?d :block/parent ?b]
     ]
     [
       [descendant ?d ?b]
       [?d :block/parent ?parent]
       (descendant ?parent ?b)
     ]
   ]
 ]
}
#+END_QUERY

Thank you for replying! This is close to what I want - is it possible to NOT pick up blocks this picks up blocks e.g. this block talks about [[logseq]]?

Sorry, I don’t understand your question.

No problem, let me try to clear it up. Appreciate you sticking with me :slight_smile: The idea is that sometimes I make quick blocks in my daily journal and if I forget about them. And then it’s really difficult to find them, because they’re not connected to anything else in my graph.

So the query should pick up blocks like this

- single block

- or a block with children
  - as long as its children
  - do not have any page references
  - or tag references
  - or are not referenced by their ID anywhere?

id:: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
- block with unused id

ideally, the query should return only top-level blocks, i.e. both single block and or block with childer but not as long as children to avoid duplicating the results

The query should NOT pick up any of these

- blocks referencing a [[page]]

- blocks that have a #tag

- blocks that have children
  - that either reference a [[page]]
  - blah

- blocks that have children
  - or reference a #tag
  - blah

If not to difficult, it would be good to exclude reference / embed by id. So these shouldn’t appear on the query as well

id:: bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb
- this block is referenced (so should not be returned in query results)

id:: cccccccc-cccc-cccc-cccc-cccccccccccc
- this block is embedded (so should not be returned in query results)

- ((bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb))

- {{embed ((cccccccc-cccc-cccc-cccc-cccccccccccc))}}

As I’ve been typing this, I’ve realised that the query should only search in Journals, as it’s only there the unfiltered notes will be.

Try this one:

#+BEGIN_QUERY
{
 :query [:find (pull ?block [*])
 :in $ %
 :where
   [?page :page/journal? true]
   [?block :block/parent ?page]
   (not [?block :block/refs])
   (not [?other :block/refs ?block])
   (not
     (descendant ?d ?block)
     (or-join [?d]
       [?d :block/refs]
       [?p :block/refs ?d]
     )
   )
 ]
 :inputs [
   [
     [
       [descendant ?d ?b]
       [?d :block/parent ?b]
     ]
     [
       [descendant ?d ?b]
       [?d :block/parent ?parent]
       (descendant ?parent ?b)
     ]
   ]
 ]
}
#+END_QUERY
2 Likes

That’s perfect, thank you so much!