Hello! Been scouring github (implementation, tests, and issues/discussion) as well as stack overflow and this site and haven’t been able to find a answer on my following problem.
I have the following data in a in-memory node:
(ns user
(:require
[xtdb.api :as xt]
[xtdb.node :as xt.node]))
(def n (xt.node/start-node {}))
(xt/submit-tx n [[:put :store {:xt/id 0
:name "Some Store"
:inventory
[{:display "Cool shirt"
:price 10.99
:tags [:cool :shirt :trending]}]}]])
I am then attempting to query/filter results based off a certain tag being present in the list/collection. With my current mental model, I am under the impression that the inventory
vector will be “unwrapped”, and subsequently the tags
vector will also be unwrapped and checked in order to filter the results.
(xt/q n '{:find [display price store-id]
:where [($ :store [{:xt/id store-id, :inventory [inventory ...]}])
[(. inventory :display) display]
[(. inventory :price) price]
[(. inventory :tags) [tags ...]]
[(= tags :trending)]]})
I have attempted to normalize the tag data into its own table, like so:
(xt/submit-tx n [[:put :store {:xt/id 0
:name "Some Store"
:inventory
[{:display "Some cool shirt"
:price 10.99
:tag-ids #{0 1 2}}]}]
[:put :tags {:xt/id 0, :tag :trending}]
[:put :tags {:xt/id 1, :tag :cool}]
[:put :tags {:xt/id 2, :tag :shirt}]])
But even with the above, I am not sure how to query based on the tag-ids set. I have also attempted to make the :tag-ids
field a vector to no avail.
At this point, I’m pretty confident my mental model of xtdb datalog isn’t correct, which is leading me to bash my head against a wall.
I understand the the data models are not totally normalized, I am mainly attempting to exercise and wrap my head around what is possible with xtdb. If the above example is possible to perform, how should a query be constructed? If not, any suggestions on how to model the data?
Any help with correcting my mental model as well is greatly appreciated
Finally, I haven’t had a long time to write this question out and proof all the tx
and q
operations, but I think they catch the gist of my meaning. If not, and there isn’t clarity, I am happy to clarify!
Also, I came across this github issue, which seems to be related to querying/filtering based off nested vectors. My attempt to translate the example in the github issue to the example data I’ve provided should be:
(xt/q n '{:find [store-id item]
:where [($ :stores [{:xt/id store-id} inventory])
($ [inventory {:tags tags}])
($ [tags {:as tag}])
[(= tags :trending)]]})
However, this gives a “malformed query” error.