Trying to create a new attribute where the value is the result of a transformation on a different attribute for the same entity. So, say I have a database where every entity has attribute :content. I want to have an additional attribute for every entity called :transformed whose value is the result of applying function f to :content. How would I go about this idiomatically and efficiently? Currently trying to do this by performing a transaction and assigning the value of the new attribute to the value of the function applied to a query for the value of the original attribute for that entity.
If it's not obvious, I'm fairly new to Datalog and Datascript
(doseq [included-block-ds-id (vec (ds/q '[:find ?id
:where
[?id :block/included true]]
@conn))]
(let [content (first (first (vec (ds/q '[:find ?content
:where
[?included-block-ds-id :block/content ?content]]
@conn))))]
(ds/transact! conn [[:db/add (first included-block-ds-id)
:block/hiccup (block-content->hiccup
conn
content)]])))
In general your code is correct, yet not optimal performance-wise. You can use single query to retrieve all id-content pairs. Then build a single transaction out of them using
for. Then transact it all at once.Notice that it’s in general a good idea to take an immutable value of your database at some point in time and then do all calculations based on it (e.g. in passing to
block-content->hiccupfunction). Only pass conn when you need function to alter the db.You don’t need it in this case, but in general, if you only need to look up attributes on a single entity, it’s much more efficient to use
ds/entityinstead of query: