clojure - Obtener todos los campos de una entidad Datomic
(5)
La sección ''Incrustado'' del documento de consultas y reglas de Datomic dice:
Los lenguajes de consulta como SQL están orientados alrededor de un modelo cliente-servidor donde, en una sola conversación, tendrá que:
- Responda su pregunta fundamental, por ejemplo, quién compró los calcetines este mes.
- Recupere toda la información adicional requerida para los informes y el procesamiento, por ejemplo, cuáles son sus nombres y direcciones de correo electrónico.
Lo último no es realmente una consulta, es solo una navegación mecánica a la información relacionada.
Aunque aprecio la honradez de la ortogonalidad de los dos aspectos mencionados, creo que a menudo necesitaré recuperar una entidad completa, cualquiera que sea su atributo.
Por lo que sé, las consultas suelen tener este formulario:
(datomic.api/q ''[:find ?name ?age ?email
:where
[?e :myapp/name ?name]
[?e :myapp/age ?age]
[?e :myapp/email ?email]]
(db conn))
Si quisiera recuperar las entidades que tienen atributos N, las tendría para enumerarlas en cada consulta, lo que me parece tedioso y propenso a errores.
¿Cómo decirle a Datomic que recupere las entidades con todos los campos en los que se persistieron, sin tener que especificarlas explícitamente?
datomic.api/touch
Existe una función específica touch para simplemente "Tocar" todos los atributos de la entidad. Entity devuelta por la función de entity es perezosa y el valor del atributo se devuelve solo cuando se accede, la función datomic.api/touch recupera con entusiasmo todos los atributos de la entidad.
Ejemplo:
(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 "[email protected]", :user/password "xxxxxx", :db/id 17592186046433}
No lo he probado, pero si lo recuerdo correctamente, puedes poner una variable como el nombre del atributo
(datomic.api/q ''[:find ?key ?value
:where
[?e ?key ?value]]
(db conn))
Puede usar la pull
para obtener todos los campos de una entidad, o incluso solo una selección. Usando ''[*]
como el patrón de extracción recuperará todos los campos
Consulte la documentación de extracción para obtener más información.
Para obtener todos los campos de una entidad con id eid
use:
(d/pull (db conn) ''[*] eid)
Pull también se puede utilizar en consultas:
(datomic.api/q ''[:find (pull ?e [*])
:where
[?e :myapp/name]
(db conn))
Tener la entidad (id) de consulta como:
=> (def eid (d/q ''[:find ?e :where [?e :myapp/name "Fred"]] (db conn)))
Usted puede obtener el mapa de entidad:
=> (def ent (d/entity (db conn) (ffirst eid)))
para que pueda acceder a los campos / atributos sin hacer una consulta adicional:
=> (seq ent)
;; ([:myapp/name "Fred"] [:myapp/age 16] [:myapp/email "[email protected]"])
Sin embargo, puede ser más fácil obtener las llaves primero:
=> (keys ent)
;; (:myapp/name :myapp/age :myapp/email)
Incluso puede obtener claves inversas (atributos ref "extraños" que apuntan a esta entidad) usando el siguiente truco:
=> (.touch ent)
=> (keys (.cache ent))
datomic.api/entity proporciona dicha funcionalidad.
Simplemente tiene la idea de que el mapa devuelto tiene una representación personalizada que oculta todos los campos pero :db/id
. Uno puede acceder a esos campos, pero imprimirlos requiere fusionar el mapa en un mapa de Clojure regular.