Fork me on GitHub

Hello, I'm trying to figure out how to model relationships in a a graph database, and I've got a puzzle. I want to be able to link one entity to another multiple times:

(d/transact db/conn [{:db/ident       :container/name
                        :db/valueType   :db.type/string
                        :db/unique      :db.unique/identity
                        :db/cardinality :db.cardinality/one}
                       {:db/ident       :container/stuff
                        :db/valueType   :db.type/ref
                        :db/cardinality :db.cardinality/many}
                       {:db/ident       :thing/name
                        :db/valueType   :db.type/string
                        :db/unique      :db.unique/value
                        :db/cardinality :db.cardinality/one}])
  (d/transact db/conn [{:container/name "a"}
                       {:container/name "b"}])
  (d/transact db/conn [{:thing/name "thing1"}
                       {:thing/name "thing2"}
                       {:thing/name "thing3"}])
  (d/transact db/conn [{:container/name "a"
                        :container/stuff   [[:thing/name "thing3"]]}
                       {:container/name  "b"
                        :container/stuff [[:thing/name "thing1"]
                                                    [:thing/name "thing1"]  ; note that I'm repeating "thing1" twice
                                                   [:thing/name "thing2"]]}])

  (d/q '[:find (count  ?thing) .
         [?e :container/name "b"]
         [?e :container/stuff ?thing]]
  ;;=> 2    I would expect this to return 3


am I approaching this the wrong way? Should I have a separate :thing/count attribute?


Datomic facts are sets, so there are no duplicate facts. You can’t assert “b contains thing1” multiple times


Having a count entity is unlikely to help because you’re going to run in to the same problem when you try to decrement


Maybe you could make “stuff” attr a tuple of thing-ref and count >=1


Stepping back though, what are you trying to model?


I want to learn fact-modeling and so I'm building an api for a pen and paper RPG rulebook. I'm trying to model advances. Each class has a set of advances, some of which they can take multiple times. A lot of those advances are shared between classes as well.


In sql terms, this would just be a join table with (advance_id, class_id, count), I think. But I'm not sure how to express that here.


Could you use something like this? :db/valueType :db.type/tuple :db/tupleTypes [:db.type/ref :db.type/long] :db/cardinality :db.cardinality/many :db/doc "Tuples of [Advance-Ref, Count]"


I'm currently playing around with datahike which doesn't support tuple types, so I can't try that out right now.


Currently, I've just removed the :db/unique property and I'm just dealing with the duplicates


the denormalization bugs me a bit, though

Ivar Refsdal11:02:38

Should lookup refs work with tuple attributes? Example code here that does not work as expected: Or am I missing something? Thanks.


Apparently pull does not work with ref. According to this gist Although I don't know where is that list of valid :db.type/ref for tuples.


Running datomic on-prem 0.9.5951 in AWS EB, the connection is created on server init. I'm seeing the following exception some time after a web service starts. A google search only returns one hit (a slack thread from Feb 2014!) Has anyone else encountered this, or may be able to hint at what might be the issue?

08:59:48.688 WARN  datomic.common [clojure-agent-send-off-pool-3]
... caused by ...
java.lang.IllegalStateException: Connection pool shut down