Closed motosota closed 9 years ago
Once we have NOT, it should be pretty straightforward:
(d/q '[:find ?b
:in $ [?ref ...]
:where [_ ?ref ?b]
(not [?b _ _])]
db
(for [[attr props] (:schema db)
:when (= :db.type/ref (:db/valueType props))]
attr))
It’s not very performant, but should work.
Without it, simples way to do this is just to walk over the database and build such a list on your own:
(let [eids (for [datom (d/datoms db :eavt)]
(:e datom))
refs (for [[attr props] (:schema db)
:when (= :db.type/ref (:db/valueType props))
datom (d/datoms db :avet attr)]
(:v datom))]
(clojure.set/difference (set refs) (set eids)))
Thanks for that, makes a lot of sense. I've come up with a slightly different solution to the problem.
The background is that I'm listening to transaction changes in datomic, and pushing allowed datoms from that transaction to subscribed datascript clients. This can sometimes result in new entities being created (which the client receives) referencing existing entities that the client doen't know about (because at the time it collected it's initial allowed datoms, that entity wasn't part of the allowed list).
An example would be a (new) service at an (existing) buliding - the client needs to know that it's missing the building information and then fetch it (since the creation of the service with a ref to the building now gives the client the right to know about the building).
Based Rich Hickey's answer here: https://groups.google.com/forum/#!searchin/datomic/existence/datomic/jZYXqtB4ycY/sbfHvVm6P5oJ and based on the datomic documention which says "Entities are not suitable for existence tests, which should typically be performed via lookup of a unique identity.", I have decided to avoid existential angst..
So I am creating a uuid for all entities. My business rules will mean that a uuid can never be retracted.
So then in the client I will lookup all entities which have a :service/entity reference to them, but do not have a :uuid attribute (using the "not" workaround in your tips and tricks wiki). That will identify my "missing" entities - the client can then request the datoms for those entities to get itself in-sync.
Possibly one for the wiki..
I am trying to list all entities that are referenced by other entities, but which themselves have no attributes.
Or in other words A references B and B has not yet been transacted into the DB. I want to find all "B-like" entities.
Hope this makes sense - any pointers appreciated - am going round in circles with this one..