Using Datomic, I'm trying to think of how can I nest a list within a list?
An example Clojure data structure would be something (see fig.1). I know that Datomic has the notion of references (ex. in fig.2). But those just look like scalar types, not objects (per se).
[{:id 0,
:symbol DDD,
:company 3D Systems Corporation,
:price-difference 1.3100000000000023,
:event-list [{high 35.11,
tickerId 0,
WAP 34.491,
open 35.07,
date 20130426,
count 3403,
low 33.8,
hasGaps false,
close 34.53,
field historicalData,
volume 8667,
type historicalData}]}]
fig.1
{:db/id #db/id[:db.part/db]
:db/ident :district/region
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
:db/doc "A district region enum value"
:db.install/_attribute :db.part/db}
;; district/region enum values
[:db/add #db/id[:db.part/user] :db/ident :region/n]
[:db/add #db/id[:db.part/user] :db/ident :region/ne]
[:db/add #db/id[:db.part/user] :db/ident :region/e]
[:db/add #db/id[:db.part/user] :db/ident :region/se]
[:db/add #db/id[:db.part/user] :db/ident :region/s]
[:db/add #db/id[:db.part/user] :db/ident :region/sw]
[:db/add #db/id[:db.part/user] :db/ident :region/w]
[:db/add #db/id[:db.part/user] :db/ident :region/nw]
fig.2
[EDIT]
Actually, I think I might have found the answer here. I was going through the Day-Of-Datomic code base, and found the example below. But I'm still not clear on what explicitly ties the :comments namespace to the :comment/body (or :comment/author) namespace(s). Does Datomic just use convention to link :comments to :comment ?
;; comments
[{:db/id #db/id[:db.part/db]
:db/ident :comments
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db/isComponent true
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :comment/body
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :comment/author
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}]
fig.1
You can't directly persist multi-dimensional lists/vectors but you can use a linking entity to accomplish something similar:
;; sample attributes
[{:db/id #db/id[:db.part/db]
:db/ident :some/ref-value
:db/valueType :db.type/ref
:db/isComponent true
:db/cardinality :db.cardinality/many
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :some/list-value
:db/valueType :db.type/string
:db/cardinality :db.cardinality/many
:db.install/_attribute :db.part/db}]
;; [["a" "b" "c"]["d" "e" "f"]]
[{:db/id #db/id[:db.part/user -1]
:some/list-value ["a" "b" "c"]}
{:db/id #db/id[:db.part/user -2]
:some/list-value ["d" "e" "f"]}
{:db/id #db/id[:db.part/user]
:some/ref-value [#db/id[:db.part/user -1] #db/id[:db.part/user -2]]}]
Note that you can use negative numbers to link entities together. They will be replaced by real entity ids when you transact them.
EDIT: Starting with version 0.8.4020, Datomic supports nested component entities (containment relationships specified by :db/isComponent
) as part of the transaction data. e.g.
;; [["a" "b" "c"]["d" "e" "f"]]
[{:db/id #db/id[:db.part/db]
:some/ref-value [{:some/list-value ["a" "b" "c"]}
{:some/list-value ["d" "e" "f"]}]}]
The nested maps expand into two sub-entities, both created in the same partition as the container/parent entity. For a full code sample, see https://gist.github.com/a2ndrade/5820364
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With