java - 在 Datomic 中更新具有多个基数的属性的事务

标签 java datomic

我搜索了两天,没有看到任何与此相关的代码。这是我见过的唯一的 java 代码,但它并不完全是我想要的。

conn.transact(list(list("db.fn/cas", datomic_id, "attribute you want to update", old value, new value))).get();

我已经尝试使用旧值中的单个值和新值中的单个值来尝试此代码,但它只是堆叠信息而不是覆盖它。 示例:旧值是鸡,新值是鱼。交易后,它是[鸡,鱼],而不是我期望的只是[鱼],并且鸡将被移入文件(历史)。

所以问题是,如何引用旧数组值以及如何为新值提供一个数组,以便它将按照我预期的方式更新,如上所述。

我记得在某处读过,在幕后它只是链接到一个属性的一系列值。如果是这种情况,是否意味着我必须找到字符串的原子 id 并更改它?如果它不在新列表中,还必须将其删除吗?

最佳答案

仅供引用,这些是我目前用于此类任务的通用事务函数(从 Clojure 声明,但如果需要的话应该很容易适应 Java):

[{:db/ident :bsu.fns/replace-to-many-scalars,
  :db/doc "Given an entity's lookup ref, a to-many (scalar) attribute, and a list of new values,
 yields a transaction that replaces the old values by new ones"
  :db/id (d/tempid :db.part/user),
  :db/fn (d/function
           '{:lang :clojure,
             :imports [],
             :requires [[datomic.api :as d]],
             :params [db entid attr new-vals],
             :code (let [old-vals (if-let [e (d/entity db entid)] (get e attr) ())
                         to-remove (remove (set (seq new-vals)) old-vals)]
                     (concat
                       (for [ov to-remove] [:db/retract entid attr ov])
                       (for [nv new-vals] [:db/add entid attr nv]))
                     )}),
  }
 {:db/ident :bsu.fns/to-many-retract-all-but,
  :db/doc "Given an entity lookup ref, a to-many (entity) attribute, and a list of lookup refs
  expands to a transaction which will retract all the [origin `to-many-attr` target] relationships but those for which target is among the `to-spare-lookup-refs`"
  :db/id (d/tempid :db.part/user),
  :db/fn (d/function
           '{:lang :clojure,
             :imports [],
             :requires [[datomic.api :as d]],
             :params [db origin to-many-attr to-spare-lookup-refs],
             :code (let [old-targets-ids (d/q '[:find [?t ...] :in $ ?to-many-attr ?origin :where [?origin ?to-many-attr ?t]]
                                           db to-many-attr origin)
                         to-spare-ids (for [lr to-spare-lookup-refs] (:db/id (d/entity db lr)))
                         to-delete (->> old-targets-ids (remove (set to-spare-ids)))]
                     (for [eid to-delete] [:db/retract origin to-many-attr eid])
                     #_[old-targets-ids to-update-ids to-delete])}),
  }]

我根本不声称它们具有最佳性能或设计,但到目前为止它们对我来说很有效。 HTH。

关于java - 在 Datomic 中更新具有多个基数的属性的事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36356933/

相关文章:

java - 从 Controller 转发到静态 html 页面

java - 带有 Android 位图类的 Google App Engine

limit - Datomic Free 可以处理多少吞吐量?

clojure - 在 Datomic 中,在没有撤回的情况下查询字段历史记录?

clojure - 对于此模式,在 Datomic 领域中更惯用的选项是什么?

java - 等待 selenium webdriver 直到加载完成

java - 如何通过 ELB 将 HTTPS 流量路由到运行 Java JHipster webApp 的 EC2 容器

java - 如何在android中获取临时文件的文件大小?

clojure - 在查询中使用 Datomic pull

clojure - 包含数据依赖项时,lein 环 headless 服务器失败