Clarice Bouwer
Clarice Bouwer

Reputation: 3811

How do I pull all entities linked from another entity in Datomic?

I don't know how to word my question.

:host/id has a link to :server/id. I want to pull all servers linked to a specific host.

I've tried several approaches but I get either an empty result, all results or an IllegalArgumentExceptionInfo :db.error/not-a-keyword Cannot interpret as a keyword.

I tried following the documentation but I keep getting lost. Here are my attempts so far:

All hosts

(d/q '[:find (pull ?server [{:host/id [:host/hostname]}])
   :in $ ?hostname
   :where 
   [?host :host/hostname ?hostname]
   [?server :server/name]] db "myhost")

IllegalArgumentExceptionInfo

(d/q '[:find (pull ?server [{:host/id [:host/hostname]}])
   :in $ ?hostname
   :where 
   [?server :server/name ?host]
   [?host :host/hostname ?hostname]] db "myhost") 

[]

(d/q '[:find (pull ?host [{:host/id [:host/hostname]}])
   :in $ ?hostname
   :where 
   [?host :host/hostname ?hostname]
   [?host :server/name]] db "myhost")

Upvotes: 2

Views: 422

Answers (1)

rmcv
rmcv

Reputation: 1976

Assuming you have these entities in datomic:

(d/transact conn [{:host/name "host1"}])

(d/transact conn [{:server/name "db1"
                   :server/host [:host/name "host1"]}
                  {:server/name "web1"
                   :server/host [:host/name "host1"]}])

And assuming each server has a reference to host (please see schema below), in order to query which servers are linked to a host, use the reverse relation syntax '_':


(d/q '[:find (pull ?h [* {:server/_host [:server/name]}])
       :in $ ?hostname
       :where
       [?h :host/name ?hostname]]
     (d/db conn)
     "host1")

will give you:

[[{:db/id 17592186045418,
   :host/name "host1",
   :server/_host [#:server{:name "db1"} #:server{:name "web1"}]}]]

Here is the sample schema for your reference:

(def uri "datomic:free://localhost:4334/svr")
(d/delete-database uri)
(d/create-database uri)
(def conn (d/connect uri))

(d/transact conn [{:db/ident       :server/name
                   :db/cardinality :db.cardinality/one
                   :db/unique      :db.unique/identity
                   :db/valueType   :db.type/string}
                  {:db/ident       :server/host
                   :db/cardinality :db.cardinality/one
                   :db/valueType   :db.type/ref}
                  {:db/ident       :host/name
                   :db/cardinality :db.cardinality/one
                   :db/unique      :db.unique/identity
                   :db/valueType   :db.type/string}])


Upvotes: 3

Related Questions