Hey there! Finally getting around to learning XTQL
I’ve gone throught the Learn XTQL Today With Clojure, and am working w/ the dataset’s (i.e. movies and persons).
As a personal challenge, I prompted myself to solve:
“Get all the peoples names involved in making ‘RoboCop’?”
And I think there is something I may be missing conceptually.
The best query I came up with is:
(xt/q node '(-> (unify
(from :movies [{:movie/title "RoboCop"} movie/cast movie/director])
(unnest {c movie/cast})
(from :persons [{:xt/id pid} person/name])
(where (or (= pid c)
(= pid movie/director))))
(return person/name)))
However, the above yeilds:
[#:person{:name "Paul Verhoeven"}
#:person{:name "Paul Verhoeven"}
#:person{:name "Paul Verhoeven"}
#:person{:name "Ronny Cox"}
#:person{:name "Peter Weller"}
#:person{:name "Nancy Allen"}]
And I was not expecting “Paul Verhoeven” to show up 3 times, but after looking more into “unnest” I understand the why behind the repitition (i.e. the array is “unnest”-ed, then matched/joined/unified against the persons table).
I then tried to construct a vector/list like so:
(xt/q node '(-> (unify
(from :movies [{:movie/title "RoboCop"} movie/cast movie/director])
(unnest {c (conj movie/cast movie/director)})
(from :persons [{:xt/id pid} person/name])
(where (or (= pid c)
(= pid movie/director))))
(return person/name)))
However, that yeilds the output of:
; eval (current-form): (xt/q node '(-> (unify (from :movies [{:mo...
; (err) Execution error (IllegalArgumentException) at xtdb.error/illegal-arg (error.clj:11).
; (err) conj not applicable to types list and list
Given I was not accounting for there being a list of id’s for :movie/director
.
Finally, I attempted to conditionally call conj
or concat
depending
on if :movie/director
was a list/vector or not, to no avail, like so:
(xt/q node '(-> (unify
(from :movies
[{:movie/title "RoboCop"}
movie/cast
movie/director])
(unnest
{a (cond
(list? movie/director)
(concat movie/cast movie/director)
(conj movie/cast movie/director))})
(from :persons [{:xt/id a} person/name]))
(return person/name)))
and I also tried using with
:
(xt/q node '(-> (unify
(from :movies
[{:movie/title "RoboCop"}
movie/cast
movie/director])
(with
{all (cond
(list? movie/director)
(concat movie/cast movie/director)
(conj movie/cast movie/director))})
(unnest {a all})
(from :persons [{:xt/id a} person/name]))
(return person/name)))
Both yeilded:
; eval (current-form): (xt/q node '(-> (unify (from :movies [{:mo...
; (err) Execution error (IllegalArgumentException) at xtdb.error/illegal-arg (error.clj:11).
; (err) list? not applicable to types list
All the above to say, I’m stumped w/ how to solve this at this point in time. I also tried multiple (from :persons ...)
, which yeilded an empty result.
Given the context of the above, what am I not considering/missing with respect to the current API? How should I go about solving the prompt at the start?
And finally, really great work to the whole team at Juxt for this peice of tech. Really excited to see v2 mature and have been enjoying diving back in and reading the dev diaries. Keep it up!