-
-
Notifications
You must be signed in to change notification settings - Fork 308
Tips & tricks
Unlike Datomic, in DataScript schema is just a map kept separate from database datoms. It means you cannot query it as you would in Datomic, but you can query it just as any other collection. Use [[?attr [[?aprop ?avalue] ...]] ...]
destructuring form to convert nested maps into a flat collection of facts.
For example, following query will return all datoms from a DB which attribute has cardinality many:
(def schema
{ :entry/id {:db/unique :db.unique/identity}
:entry/child {:db/cardinality :db.cardinality/many
:db/valueType :db.type/ref}
:entry/first-child {:db/valueType :db.type/ref} })
(def db (-> (datascript/empty-db schema)
(datascript/db-with [[:db/add 1 :entry/id "a"]
[:db/add 1 :entry/child 2]
[:db/add 1 :entry/child 3]
[:db/add 1 :entry/first-child 2]])))
(datascript/q '[:find ?entity ?attr ?value
:in $ [[?attr [[?aprop ?avalue] ...]] ...]
:where [(= ?avalue :db.cardinality/many)]
[?entity ?attr ?value]]
db (:schema db))
=> #{[1 :entry/child 3] [1 :entry/child 2]}
DataScript DB support EDN serialization natively:
(pr-str (datascript/empty-db)) => "#datascript/DB {:schema {} :datoms[]}"
Do read database from a reader,
In Clojure use datascript/data-readers
:
(clojure.edn/read-string
{:readers datascript/data-readers}
"#datascript/DB {:schema {} :datoms[]}")
In ClojureScript #datascript/DB
handler is installed by default, just use
(cljs.reader/read-string "#datascript/DB {:schema {} :datoms[]}")
datascript/filter
filters individual datoms, but what if you want to keep whole entities? For example, you want to filter a DB leaving out only persons whose name is "Ivan"
:
(d/filter db
(fn [db datom]
(or
;; leaving all datoms that are not about :person/* as-is
(not= "person" (namespace (:a datom)))
;; for :person/* attributes take entity id
;; and check :person/name on that entity using db value
(let [eid (:e datom)
entity (d/entity db eid)]
(= "Ivan" (:person/name entity))))))