Skip to content

Instantly share code, notes, and snippets.

@k1m190r
Created June 9, 2012 10:30
Show Gist options
  • Save k1m190r/2900464 to your computer and use it in GitHub Desktop.
Save k1m190r/2900464 to your computer and use it in GitHub Desktop.
How to find entities that do not have a particular attribute?
(use '[datomic.api :only [q db] :as d]
'clojure.pprint
'clojure.repl)
(do
(def *uri "datomic:mem://likes")
(d/create-database *uri)
(def *conn (d/connect *uri)))
;; define utilities
(do
(defmacro tx [ll#]
`(d/transact *conn ~ll#))
(defmacro ent [eid]
`(d/entity (db *conn) ~eid))
(defmacro f [query]
`(q ~query (db *conn)))
(defmacro p [form]
`(-> ~form seq pprint)))
;; define schema
(tx [{:db/id #db/id[:db.part/db]
:db/ident :pers/age
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "Age of the person."
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :pers/likes
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/many
:db/doc "Who likes who/ what."
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :pers/name
:db/valueType :db.type/keyword
:db/cardinality :db.cardinality/one
:db/doc "Name as keyword"
:db.install/_attribute :db.part/db}
{:db/id #db/id[:db.part/db]
:db/ident :likes
:db.install/_partition :db.part/db}])
;; data
(tx [{:db/id #db/id [:db.part/user]
:pers/name :sally
:pers/age 21
:pers/likes :opera}
{:db/id #db/id [:db.part/user]
:pers/name :fred
:pers/age 42
:pers/likes :pizza}
{:db/id #db/id [:db.part/user]
:pers/name :ethel
:pers/age 42
:pers/likes :sushi}
{:db/id #db/id [:db.part/user]
:pers/name :john
:pers/age 40}])
(do
(tx
[{:db/id #db/id [:db.part/user]
:db/ident :attr-missing?
:db/fn (d/function
{:lang :clojure
:params '[db pers# attrib#]
:code '(-> db (datomic.api/entity pers#) attrib# nil?)})}])
(def attr-missing? (-> *conn db (d/entity :attr-missing?) :db/fn))
)
(do
(tx
[{:db/id #db/id [:db.part/user]
:db/ident :attr-exists?
:db/fn (d/function
{:lang :clojure
:params '[db pers# attrib#]
:code '(-> db (datomic.api/entity pers#) attrib# nil? not)})}])
(def attr-exists? (-> *conn db (d/entity :attr-exists?) :db/fn))
)
(p (f '[:find ?name :where
[ ?e :pers/name ?name]]))
;; ([:john] [:sally] [:ethel] [:fred])
(p (f '[:find ?name :where
[ ?e :pers/name ?name]
[(user/attr-exists? $ ?e :pers/likes)]]))
;; ([:sally] [:ethel] [:fred])
(p (f '[:find ?name :where
[ ?e :pers/name ?name]
[(user/attr-missing? $ ?e :pers/likes)]]))
;; ([:john])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment