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

问题描述 投票:0回答:1

试图创建一个新的属性,其值是对同一实体的不同属性进行转换的结果。所以,假设我有一个数据库,每个实体都有一个属性。: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)]])))
clojurescript datalog datascript
1个回答
1
投票

总的来说,你的代码是正确的,然而从性能上来说并不是最佳的。你可以使用单个查询来检索所有的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))
© www.soinside.com 2019 - 2024. All rights reserved.