Advanced Query - Find blocks with link in property that has multiple links

Hi everyone!

First of all, I want to thank this great community! :tada:
I’ve learned so much about Logseq, and it became my only tool for work and personal life.

I think that Datalog is the most powerful tool I’ve seen in a KT system, and it’s a game changer. Writing information is easy; the challenge is to retrieve it.

For this reason, I want to master Advanced Queries, which have quite a steep learning curve :mountain_snow:.
I’ve been searching around for days without finding a way of doing what the following:

Inside journals, I’m using blocks to keep track of meetings. Meetings have multiple properties:

-- [[2023-07-29]] (page)
   -- 10:00-10:30 Weekly sync (block title)
      -- Properties:
        - type: [[meeting]]
        - participants: [[Goofy]] [[Donald Duck]] [[Frozen]] [[Buzz Lightyear]]
        - from: 10:00
        - to: 10:30
        - project: [[Projects/Counquer the world]]

What I’m trying to achieve is:
“Find all blocks with property type [[meeting]] and [[Frozen]] in the list of participants.”

I can find the blocks that are meeting, but I’m not able to find the ones with Frozen :frowning:

I’m trying to find the answer in the style of:

For each p in participants:
   if p ==  [[Frozen]]:
      return true

But probably, I’m thinking in the wrong way for Datalog. :thinking:


  • Have you mastered Simple Queries?
  • Do you use actual Logseq properties (e.g. type:: with double :) or do you have a separate block -- Properties:?
  • Could you share your current query?

In addition to the questions from @mentaloid
It is a good idea to define property values with comma separation and in config say to process them as pages.
This makes fetching the data easier in queries.


Then look into:

Hi, thank you for the help and sorry for my late reply

  1. yes, with the Simple Queries I’m all good. I know simple queries can be used within advanced queries, but my goal is to get used to the Advanced Queries :slight_smile:
  2. I use actual Logseq properties → type::
  3. I was able to figure out how to make it work:
:title "Meetings"
:query [
:find (pull ?b [*])
:in $ ?participant
[?b :block/properties ?prop]
[(get ?prop :type) ?type]
[(= ?type #{"meeting"})]
[(get ?prop :participants) ?participants]
[(contains? ?participants ?participant)]
:inputs ["Frozen"]

For reference, this is what the block looks like:

DONE 11:00-11:30 Project sync
type:: [[meeting]]
date:: [[2023-08-04]]
from:: 11:00
to:: 11:30
project:: [[Projects/Counquer the world]]
participants:: [[Goofy]] [[Donald Duck]] [[Frozen]] [[Buzz Lightyear]]

Thank you for the suggestion.

By enabling that option, would it mean I should search the participants by refs instead of by text?
If yes, in a mixed case like the one below, Donal Duck doesn’t have a page. How can I find the meetings with him as a participant?
From the DB schema, there is the following comment in the code (github link). Does it mean that I need to search Donald Duck by text?

DONE 11:00-11:30 Project sync
type:: [[meeting]]
date:: [[2023-08-04]]
from:: 11:00
to:: 11:30
project:: [[Projects/Counquer the world]]
participants:: [[Goofy]], Donald Duck, [[Frozen]], [[Buzz Lightyear]]

Easier. The option enables all to be interpreted as page. So you don’t need the [[ ]] anymore and all will be retrievable using :block/refs.

For example I use the property “onderwerp” (subject) in this manner.
PKM only exists in the value of this property:
onderwerp:: PKM
And I can use this query regardless. To find all the blocks that have this subject. Because it is still a page thanks to that config option.

{:title [:b "Referenties"]
 :query [:find (pull ?b [*])
  :in $ ?onderwerp
   [?p :block/name ?onderwerp]
   [?b :block/refs ?p]
 :inputs ["pkm"]