I'm trying to set up a tagging systems in my db, I have added two attrs to handle this:
{:db/ident :metadata/tags
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db/isComponent true}
{:db/ident :metadata/tag
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/one
:db/index true}
This works more or less in terms of assigning tags, but how I am encountering some problems in filtering for tags. I think when doing this I assumed that I'd be able to reference the tags the way one would idents, as a keyword, e.g. :tag1
. But it's proving a bit more challenging.
My first approach has been to use a query filter expression, something like this (non-working attempt):
'[:find (pull ?doc [*])
:in $ ?tags
:where [?doc :arb/metadata ?meta]
[?doc :metadata/tags ?tagset]
[(every? (set ?tags) ?tagset)]]
where :tags is a supplied list of tag keywords, e.g. [:tag1 :tag2 ...]
. But the result of the pull doesn't quite work here because for each tag the pull returns a map including the :db/id
as well as the tag e.g.:
[#:arb{:metadata
[{:db/id 17592186045497,
:metadata/tags
[{:db/id 17592186045498, :metadata/tag :tag1}
{:db/id 17592186045499, :metadata/tag :tag2}],
I thought that I could still work with this by mapping over the ?tagset
to extract just the tag keywords, but inside the map expression '?tagset` ends up being out of scope. So I'm a bit stumped about how I should approach this problem, which I feel must be somewhat common... Any tips?