尝试创建一个新属性,其中的值是对同一实体的不同属性进行转换的结果。因此,假设我有一个数据库,其中每个实体都有:content属性。我希望每个名为:transformed的实体都有一个额外的属性,它的值是将函数f应用于:content的结果。我该如何用惯用法和有效率来做这件事呢?当前试图通过执行事务并将新属性的值分配给应用于查询该实体的原始属性的值的函数的值来做到这一点。
如果不是很明显,我对Datalog和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)]])))发布于 2020-05-28 01:17:33
一般来说,您的代码是正确的,但在性能方面并不是最佳的。您可以使用单个查询来检索所有id-content对。然后使用for构建单个事务。然后一次把它全部处理掉。
(let [db @conn
id+content (ds/q '[:find ?id ?content
:where [?id :block/included true]
[?id :block/content ?content]]
db)
tx (for [[id content] id+content]
[:db/add id :block/hiccup (block-content->hiccup db content)])]
(ds/transact! conn tx))请注意,通常情况下,在某个时间点获取数据库的不可变值,然后基于它进行所有计算(例如,传递给block-content->hiccup函数)是一个好主意。当你需要函数来修改db时,只传递conn。
在这种情况下,您不需要它,但通常情况下,如果您只需要查找单个实体的属性,则使用ds/entity而不是查询要高效得多:
(:block/content (d/entity db id))https://stackoverflow.com/questions/62032169
复制相似问题