我搜索了两天,但没有看到任何关闭此代码的代码。这是我见过的java中唯一的代码,并不是我想要的。
conn.transact(list(list("db.fn/cas", datomic_id, "attribute you want to update", old value, new value))).get();
我尝试使用旧值中的单个值和新值中的单个值来尝试此代码,但它只是堆叠信息而不是覆盖它。 例如:旧值是鸡,新值是鱼。在交易之后,它是[鸡肉,鱼]而不是我预期的[鱼],鸡将进入存档(历史)。
所以问题是,你如何引用旧的数组值,以及如何将新值赋予数组,以便它像我预期的那样更新如上所述。
我记得在某个地方阅读它只是一系列连接到一个属性的值。如果是这种情况,那是否意味着我必须找到字符串的数据组ID并进行更改?如果它不在新列表中,还必须删除它吗?
答案 0 :(得分:2)
仅供参考,这些是我目前用于此类任务的通用事务函数(从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。
答案 1 :(得分:0)
如果你需要"最后一次写作获胜"样式一致的解决方案,以替换卡的许多属性的特定实体的所有值,最好的办法是使用transaction function。您可以采取以下方法: