Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all fields from a Datomic entity

The 'Embedded' section of the Datomic Queries and Rules document says:

Query languages like SQL are oriented around a client-server model where, in a single conversaton, you are going to have to both:

  • Answer your fundamental question, e.g. who bought socks this month.
  • Recover any additional information required for reporting and processing, e.g. what are their names and email addresses.

The latter is not really a query, it is just a mechanical navigation to related information.

While I appreciate how the orthogonality of the two different mentioned aspects is honored, I think I'll often need to retrieve a whole entity, whichever its attributes are.

As far as I know, queries typically have this form:

(datomic.api/q '[:find ?name ?age ?email
                 :where
                 [?e :myapp/name ?name]
                 [?e :myapp/age ?age]
                 [?e :myapp/email ?email]]
               (db conn))

If I wanted to retrieve entities that have N attributes, I'd have them to list them all in each query, which seems tedious and error-prone to me.

How to tell Datomic to retrieve the entities with all the fields they were persisted with, without having to specify them explicitly?

like image 781
deprecated Avatar asked Jan 07 '13 03:01

deprecated


2 Answers

Having the entity (id) from query like:

=> (def eid (d/q '[:find ?e :where [?e :myapp/name "Fred"]] (db conn)))

you can get the EntityMap:

=> (def ent (d/entity (db conn) (ffirst eid)))

so you can access fields/attributes without making additional query:

=> (seq ent)
;; ([:myapp/name "Fred"] [:myapp/age 16] [:myapp/email "[email protected]"])

however it may be easier to get the keys first:

=> (keys ent)
;; (:myapp/name :myapp/age :myapp/email)

You can even get reverse keys ("foreign" ref attributes that point to this entity) using the following trick:

=> (.touch ent)
=> (keys (.cache ent))
like image 161
Grzegorz Luczywo Avatar answered Nov 12 '22 05:11

Grzegorz Luczywo


You can use pull to get all fields from an entity, or even just a selection. Using '[*] as the pattern for pull will retrieve all fields

See the pull documentation for more information.

To get all fields from an entity with id eid use:

(d/pull (db conn) '[*] eid)

Pull can also be used in queries:

(datomic.api/q '[:find (pull ?e [*])
                 :where
                 [?e :myapp/name]
               (db conn))
like image 20
ChrisBlom Avatar answered Nov 12 '22 06:11

ChrisBlom