{:db/ident :meta/tag
:db/valueType :db.type/tuple
:db/tupleAttrs [:meta/tag-namespace :meta/tag-key :meta/tag-value] ;; all unique strings
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity}
Then
{:meta/tag-namespace "Test"
:meta/tag-key "Test"
:meta/tag-value "Test"}
Lookup refs work as I would expect!
(d/entity db [:meta/tag ["Test" "Test" "Test"]])
; #:db{:id 17592186574549}
I can query with hardcoded values:
(d/q '[:find ?t :in $
:where [?t :meta/tag ["Test" "Test" "Test"]]]
db)
; #{[17592186574549]}
And I can construct tuples outside and pass them in:
(d/q '[:find ?t :in $ ?tt
:where [?t :meta/tag ?tt]]
db ["Test" "Test" "Test"])
; #{[17592186574549]}
Construct tuples inside Datalog - this doesn't work:
(d/q '[:find ?t :in $ ?tn ?tk ?tv
:where [?t :meta/tag [?tn ?tk ?tv]]]
db "Test" "Test" "Test")
; #{}
You have to use the tuple
helper:
(d/q '[:find ?t :in $ ?tn ?tk ?tv :where
[(tuple ?tn ?tk ?tv) ?tt]
[?t :meta/tag ?tt]]
db "Test" "Test" "Test")
; #{[17592186574549]}
Raw index access:
(seq (d/datoms db :avet :meta/tag ["Test" "Test" "Test"]))
(#datom[17592186574549 1116 ["Test" "Test" "Test"] 13194140063444 true])
Partial tuples (padded with nil
) works with seek-datoms
:
(seq (d/seek-datoms db :avet :meta/tag ["Test" nil nil]))
(#datom[17592186574549 1116 ["Test" "Test" "Test"] 13194140063444 true])
To backfill composite tuple attributes, you have to re-transact the source values.
Composite attributes are entirely managed by Datomic–you never assert or retract them yourself. Whenever you assert or retract any attribute that is part of a composite, Datomic will automatically populate the composite value.
The transactor won't transact anything that's already currently true, but it will trigger the behaviour that creates the composite tuple.
Update: Sample Datomic Client code that does this, from Cognitect:
Homogenous tuples, although they are variable length, you can only have at most 8 values. This means that although it does provide a way to set the order of a bunch of values, it can't be used to set an arbitrary order of child entities e.g. sections in a page if there are more than 8 children.
Still, it is useful if you know you'll never have more than 8 arbitrarily ordered children.
The docs don't list :db.type/ref
as a valid value, but the transactor does accept :db/tupleType :db.type/ref
, and it accepts entity ids as tuple values, whether as raw Longs or lookup-refs.
d/entity
won't process entitys referenced in tuples, and you can't use d/pull
to walk into entities referenced this way.
When an entity ID appears in a tuple, it doesn't also create a :vaet
index datom.
My guess is refs are treated as longs once they're validated as entity ids, and no further ref-like behaviour occurs.
@mikew1 and others: I cobbled together a tx-function that adds support for using composite tuples with refs in transactions:
Here's an example of usage: