This question is just one part of a more complex query I want to build but datalog is completely opaque to me and I want to understand one step at a time.
If I have pages with type:: [[Movie]]
then this query should get me all such pages:
#+BEGIN_QUERY
{
:title [:h2 "All Movies"]
:query [:find (pull ?b [*])]
:where
[?b :page/properties ?p]
[(get ?p :type) ?t]
[(= #{"Movie"} ?t)]
}
#+END_QUERY
This gets me all pages with exactly type:: [[Movie]]
, (ie. linked reference)
But my pages might have multiple type
s, eg. type:: [[Movie]], [[Non-Fiction]], [[Video]]
or whatever.
I thought contains?
might be useful? But:
#+BEGIN_QUERY
{
:title [:h2 "All Movies"]
:query [:find (pull ?b [*])]
:where
[?b :page/properties ?p]
[(get ?p :type) ?t]
[(contains? #{"Movie"} ?t)]
}
#+END_QUERY
This gets me all pages with exactly type:: Movie
(ie. unlinked reference)
Which I dont understand the logic of at all
How can I write a query to get all pages whose type
includes Movie
, regardless of if it is linked or unlinked, or if there are other type
s included?
Update, putting it here to help others.
The solution is to basically combine both.
#+BEGIN_QUERY
{:query
[:find
(pull ?p [*])
:in $ ?in
:where
[?p :block/name]
[?p :block/properties ?prop]
[(get ?prop :type) ?v]
(or [(= ?v ?in)] [(contains? ?v ?in)])],
:inputs ["Movie"]
}
#+END_QUERY
It seems strange to me that you need both, because I would have thought if A == B then A also contains B, but oh well.
quor
February 14, 2022, 2:02pm
4
What about the following?
#+BEGIN_QUERY
{
:query [
:find (pull ?b [*])
:where
[?b :block/properties ?prop]
[(get ?prop :type) ?t]
[(contains? ?t "Movie")]]
}
#+END_QUERY
Basically your first approach but with different ordering of parameters for contains?
Since Logseq is clojure-based, some stuff actually comes from vanilla clojure, contains?
is one of such things. This can be used to advantage with the help of the clojure documentation contains? - clojure.core | ClojureDocs - Community-Powered Clojure Documentation and Examples
Gives the following result for me:
ddavo
November 5, 2022, 12:46pm
5
How could I make this query case insensitive?
I.e. changing the = #{"Movie"}
so it also accepts the type “movie” in undercase
ddavo
November 5, 2022, 3:23pm
6
I think it can be done with regex, but is there an easier way?
@quor This query seems to only work for page links like [[Movie]]
. If following is given:
type:: Movie, Book
, the query did not found pages. On the other hand, this works for a single property value type:: Movie
:
[(= ?t "Movie")]]
, but not if there are multiple property values.
Is there a query that is capable or finding one value out of multiple given (not-linked) property values?