Query to find (and [[A]] (not [[B]])) but B is child to A

Hello!

I don’t think this would be hard, but I can’t really grasp the datascript/datalog. I’m decent with SQL.

What I’m after is a query that finds all blocks with reference to [[A]] and does not have a child with refence to [[B]].

The pseudo query would be (and [[A]] (not child [[B]])).

Can I use ‘regular’ query, or do I have to use ‘advanced query’?

This might be a start :point_down:

#+BEGIN_QUERY
{:title “All blocks with tag A”
:query [:find (pull ?b [*])
:where
[?p :block/name “a”]
[?b :block/refs ?p]}
#+END_QUERY

How do I get the children? I know of :parent-block

Thanks for any guidance!

Cheers!

Yes, there’s an attribute :block/parent
As for understanding datalog, if you know SQL think of datalog as follows, it is only 1 table which has a structure of 3 (there are more, but those are not needed for our purpose) columns. The first column is an id, the second is the attribute name (what in SQL would be your column name) and the third is the value of that attribute.
So select block_parent from blocks where block_id = 1
Would become
[1 :block/parent _] in datalog _ is basically “any value”.
This is what helped me understand datalog coming from SQL myself :slight_smile:
PS. Any ? is a variable.

Here’s the query you would then need:

#+BEGIN_QUERY
{:title “All blocks with tag A”
 :query [:find (pull ?b [*])
   :where
     [?p :block/name "a"]
     [?b :block/refs ?p]
     (not 
       [?r :block/name "b"]
       [?child :block/refs ?r]
       [?child :block/parent ?b]
     )
 ]
}
#+END_QUERY
3 Likes

Thank you for input!

That query gives ‘Block Render Error’. I will try to fibble around a bit!

I don’t know if the copy-paste breaks something, but I wrote the query unformatted:

#+BEGIN_QUERY
{
:title “All blocks with tag A”
:query [
:find (pull ?block [*])
:where
[?page :block/name “a”]
[?block :block/refs ?page]
(not
[?reference :block/name “b”]
[?child :block/refs ?reference]
[?child :block/parent ?block]
)
]
}
#+END_QUERY

it works, but yours does not… Can’t see any difference…

Thank you anyways!

Sorry didn’t test it :sweat_smile:
The difference is the variable names. ?b and ?p are reserved for block and pages. But sometimes Logseq gets confused about it for some weird reason… idk.
So yeah just giving those a different names solves the problem as you can see.

None of those queries works, unless replacing all with ".

1 Like