Get all fields from a Datomic entity

纵然是瞬间 提交于 2019-12-02 18:07:33

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 "fred@email.com"])

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))
Jérémie

datomic.api/touch function

There is a specific datomic.api/touch function to just "Touch" all the attributes of the entity. Entity returned by the entity function are lazy and the attribute value is returned only when accessed, the touch function eagerly retrieve all the entity attributes.

Example:

(let [entity (d/entity db-val (ffirst (d/q '[:find ?e :in $ ?email
                                             :where [?e :user/email ?email]]
                                            db-val email))]
    ;;then just d/touch the entity returned by the d/entity fn
    (d/touch entity))
=> {:user/username "gretchen", :user/email "gretchen@user.com", :user/password "xxxxxx", :db/id 17592186046433}

datomic.api/entity provides such functionality.

It just has the gotcha that the returned map has a custom representation which hides all fields but :db/id. One can access those fields, but printing them requires merging the map into a regular Clojure map.

I haven't tested it, but if I remember correctly you can just put a variable as the attribute name

(datomic.api/q '[:find ?key ?value
             :where
             [?e ?key ?value]]
           (db conn))
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!