Advanced Query: Blocks including certain keywords

Hi there :wave:
I’d like to do a query of blocks that contain some certain keywords, for example key_1 or key_2.
Org mode, property block is defined as flowing:

:PROPERTIES:
:keywords: key_1 key_2
:category: clojure

Using following statements to query failed to return results.

#+BEGIN_QUERY
{
	:title [:h2 "Multi-keyword query"]
       :query [
				:find (pull ?b [*])     
                :where
				[?b :block/properties ?p]
				[(get ?p :keywords) ?t] 
				[(contains?  #{"key_1",  "key_2"} ?t)]
         ]			 
}
#+END_QUERY

But if the block attribute only contains a certain keyword, it can be retrieved using the above query statement.
For example,

:PROPERTIES:
:keywords: key_1
:category: clojure
:END:

This will return the search results.
What I hope to achieve is that if it contains A or B, or both A and B, it can be retrieved.
Can someone assist me?Thanks.

Properties as you define them here are only a single value, namely “key_1 key_2”.
Either:

  • define them as page refs: [[key_1]] [[key_2]]
  • make it a string search:
(or
  [(clojure.string/includes ?t "key_1")]
  [(clojure.string/includes ?t "key_2")]
)

According to the statement you gave, I changed the query statement to

#+BEGIN_QUERY
{
	:title [:h2 "Multi-keyword query"]
       :query [
				:find (pull ?b [*])     
                :where
				[?b :block/properties ?p]
				[(get ?p :keywords) ?t] 
				[(or
					[(clojure.string/includes ?t "key_1")]
					[(clojure.string/includes ?t "key_2")]
				)]
         ]			 
}
#+END_QUERY

But the result is that almost all blocks are returned, blocks that do not contain the “key_1” and “Key_2” and blocks that contain other keywords are returned.

Try removing the square brackets around the or-clause, i.e. change this:

[(or
    ...
)]

…into this:

(or
    ...
)

It reported

Add the missing question mark ? at the end of the two includes , i.e. clojure.string/includes?

Is it written like this?

#+BEGIN_QUERY
{
	:title [:h2 "Multi-keyword query"]
       :query [
				:find (pull ?b [*])     
                :where
				[?b :block/properties ?p]
				[(get ?p :keywords) ?t] 
				(or
					[(clojure.string/includes? ?t "key_1")]
					[(clojure.string/includes? ?t "key_2")]
				)
         ]			 
}
#+END_QUERY

It reported

I copy-paste the last one and it works to me. Try it on an empty graph.

I managed to get your error message, after changing the values to page refs. As @Siferiax said, should be one (your last query, but with plain text) or the other (below), not both. This is with page refs:

(or
    [(contains? ?t "key_1")]
    [(contains? ?t "key_2")]
)

Very strange, in a brand new graph, there is no problem running. What’s the problem? Can it still be saved? I have written notes for two years.

  • Your notes are safe.
  • The problem is with the format of your properties.
    • When it is not consistent, queries don’t care, they just produce their report.
  • Therefore:
    • Experiment with the new graph.
      • Try different formats and queries.
    • Decide on a format and query that works best for your needs.
    • Then apply your decision on the old graph:
      • Fix the format of any properties that don’t comply.

I found that if the keywords of the block attribute contain page refs, such as [[key_1]], then such an error will be reported.

So the next step is how to quickly find the block containing page refs?

Apologies for giving a statement that didn’t work lol.
Here’s a full query that works whether you have plain text or references.
I convert ?t to a string so the string search works.
(when it contains page refs it is actually not a string, and causes errors when you try to do string operations)

#+BEGIN_QUERY
{
	:title [:h2 "Multi-keyword query"]
       :query [
				:find (pull ?b [*])     
                :where
				[?b :block/properties ?p]
				[(get ?p :keywords) ?t]
                [(str ?t) ?st]
				(or
                  [(clojure.string/includes? ?st "key_1")]
                  [(clojure.string/includes? ?st "key_2")]
                )
         ]			 
}
#+END_QUERY
1 Like

Great!It works.Thanks to @Siferiax and @mentaloid very much!Thank you!

1 Like