首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Datascript中,如何从另一个属性的值创建新属性?

在Datascript中,如何从另一个属性的值创建新属性?
EN

Stack Overflow用户
提问于 2020-05-27 06:05:15
回答 1查看 170关注 0票数 0

尝试创建一个新属性,其中的值是对同一实体的不同属性进行转换的结果。因此,假设我有一个数据库,其中每个实体都有:content属性。我希望每个名为:transformed的实体都有一个额外的属性,它的值是将函数f应用于:content的结果。我该如何用惯用法和有效率来做这件事呢?当前试图通过执行事务并将新属性的值分配给应用于查询该实体的原始属性的值的函数的值来做到这一点。

如果不是很明显,我对Datalog和Datascript还是个新手

代码语言:javascript
复制
(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)]])))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-28 01:17:33

一般来说,您的代码是正确的,但在性能方面并不是最佳的。您可以使用单个查询来检索所有id-content对。然后使用for构建单个事务。然后一次把它全部处理掉。

代码语言:javascript
复制
(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而不是查询要高效得多:

代码语言:javascript
复制
(:block/content (d/entity db id))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62032169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档