Advanced query: How to get blocks with two linked pages?

Hi all,

I’m trying to build a query that returns any block that contains two specific references.

I will illustrate it with an example:

BLOCK 1:- [[Topic A]]
          - Something important related to [[Topic B]]
BLOCK 2: Something important related to [[Topic A]] and [[Topic B]]

In this example, I would like to build a query that only returns blocks that contains [[Topic A]] and [[Topic B]], so in this example, the query would return just BLOCK 1.

I’ve tried using a simple query {{query (and [[Topic A]] [[Topic B]])}} but in this example, it would return both BLOCK 1 and BLOCK 2.
It seems that simple queries always look in the whole branch, which is not what I need.

So I’ve started learning some advanced queries, but I couldn’t build a query that works.
I’ve tried the following queries:

#+BEGIN_QUERY
  {
    :query [:find (pull ?b [*])
    :where
      [?b :block/refs ?p]
      [?p :block/name ?n]
      [(contains? #{"topic b"} ?n)]
      [(contains? #{"topic a"} ?n)]
    ]
  }
  #+END_QUERY

This one does not return any result.

#+BEGIN_QUERY
  {
    :query [:find (pull ?b [*])
    :where
      [?b :block/refs ?p]
      [?p :block/name ?n]
      (and [(contains? #{"topic b"} ?n)]
      [(contains? #{"topic a"} ?n)])
    ]
  }
  #+END_QUERY

This one throws “block render error”.
I am not sure if this “and” operator is valid.

Does anyone know if it is possible to build a query to meet these needs?

I’ve put a lot of time and effort into trying to figure this out, so I would appreciate any help.

Hey guys!

After trying some other queries, I finally was able to write a query that returns whats I need, so I will leave it may help someone else

#+BEGIN_QUERY
  {
    :query [:find (pull ?b [*])
    :where
      [?b :block/refs ?r-a]
      [?b :block/refs ?r-b]
      [?r-a :block/name "topic a"]
      [?r-b :block/name "topic b"] ]
  }
  #+END_QUERY

The correct way of doing it is to attribute two sets of references to the variable ?b, and datalog will do the rest for you, returning only the results that are present in both sets.

As someone with some basic SQL knowlodge, I am still getting used to this whole different concept of datalog queries.

Cheers,