Fork me on GitHub
#datomic
<
2024-01-23
>
Aviv11:01:36

Hey everyone, Is it possible to retract all entities/attributes that satisfy some condition? for example, :person/name :preson/age • retract all persons under the age x • retract all persons that their name not in ["a" "b"] i can’t figure out how to do it without query all persons first? (sounds like a bad performance as well) Thanks 🙏

Aviv12:01:22

Hmm, doesn’t it just mean that it would run on the transactor? I would need to query all persons and filter the ones I want first, right? In addition, for every retract that i would need i’ll have to create a new function?

wikipunk12:01:48

Datomic is data oriented, to retract data is to add transaction data that contains :db/retract for each fact you want to be removed. So, to generate that data you would use a function that queries the database for your condition and build the transaction data from that result into the :db/retract you would require. https://docs.datomic.com/cloud/tutorial/retract.html has some more information.

clj 2
👌 1
souenzzo23:01:33

BTW: It is possible to make a query return a tx-data

(d/transact conn
  (d/q '[:find ?retract ?id
         :where
         [(ground :db/retractEntity) ?retract]
         [?id :user/age ?age]
         [(< ?age 21)]]))
It is more fun than useful. But most of my database migrations were written like this.

👍 1
itaied06:01:03

I want to elaborate this question regarding consistency for the use case of "delete all employees that have been banned", where "ban" is a boolean attribute. I can query all of the employees and verify their "ban" field, and then send a transact query to retractEntity of them all. What if between the query that i have executed and the transact that I have sent, some employee has been updated from "true" to "false", i.e, the transaction should not retract him, but it would. I understand cas and how it can help us with updating attributes, and also the retract API for attributes (based on a value), but it seems like retractEntity is missing a key concept of filtering / matching to assure consistency. Wheres in a RDBM you would execute the update with the query atomically "delete .. where ban=true"

henrik07:01:55

I’d maintain that if you want this to be synchronous, you’d use a tx function in some way. Otherwise, the DB might have moved between your query and your tx.

👍 1
onetom03:01:19

maybe u can make a generic tx fn, which accepts a datalog query as an argument. that would be equivalent to the atomic DELETE ... WHERE SQL statement.

👌 1