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?
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))
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))
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