1

When I query for a list of Datomic entities, e.g like in the example below:

'[:find ?e
        :where
        [?e :category/name]]

Usually, I'd like to create a list of maps that represent the full entities, i.e

#{[1234] [2223]} => [{:category/name "x" :db/id 1234}, {:category/name "y" :db/id 2223}]

Here is my approach at the moment, in the form of a helper function.

(defn- db-ids->entity-maps
  "Takes a list of datomic entity ids retrieves and returns
  a list of hydrated entities in the form of a list of maps."
  [db-conn db-ids]
  (->>
    db-ids
    seq
    flatten
    (map #(->>
           %
           ;; id -> lazy entity map
           (d/entity (d/db db-conn))
           ;; realize all values, except for db/id
           d/touch
           (into {:db/id %})))))

Is there a better way?

Odinodin
  • 2,147
  • 3
  • 25
  • 43

2 Answers2

2

With the pull api, this is pretty easy now.

'[:find [(pull ?e [*]) ...] 
  :in $ [[?e] ...] 
  :where [?e]]
rabidpraxis
  • 556
  • 3
  • 10
  • Datomic's pull is good generally, except it does not handle enumerated values as one would expect: instead of the namespaced keywords we want, pull'ed entities have references. – limist Aug 15 '15 at 19:57
  • 1
    Correct, if you wanted to use the pull api to gather enums with a wildcard you will have to also specify the enum path explicitly: `(pull ?e [* {:enum-prop [:db/ident]}])` – rabidpraxis Aug 16 '15 at 22:05
0

I used to take this approach to save queries to the DB, the code is probably less reusable but it depends on what is more critical in your current scenario. I haven't a Datomic instance configured as I am not working with it right now so it may contain syntax error but I hope you get the idea.

(def query-result '[:find ?cat-name ?id
                :where
                [?cat-name :category/name
                [?id :db/id]])

=>

 #{["x" 1234] ["x" 2223]} 




(defn- describe-values
      "Adds proper keys to the given values."
       [keys-vec query-result]
       (vec (map #(zipmap keys-vec %) query-result)) 



(describe-values [:category/name :db/id] query-result)

=>

[{:db/id 2223, :category/name "x"} {:db/id 1234, :category/name "x"}]
Jaime Agudo
  • 8,076
  • 4
  • 30
  • 35
  • I was hoping to avoid having to spell out every attribute in the query myself and rather just return the entity. – Odinodin Nov 18 '14 at 19:35
  • I am afraid that if there aren't updates this question has already been covered http://stackoverflow.com/questions/14189647/get-all-fields-from-a-datomic-entity as you probably already saw and your approach is good enough, at least for now :) – Jaime Agudo Nov 18 '14 at 19:52