2016-04-01 19 views
1

我已經搜索了兩天,並且還沒有看到任何關閉此代碼的代碼。這是我見過的java中唯一的代碼,它不完全是我想要的。在Datomic中更新具有多個基數的屬性的交易

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

我曾嘗試這個代碼與舊值的單值和新值的單個值,但它只是堆棧的信息,而不是覆蓋它。例如:舊值是雞,新值是魚。交易後,它是[雞肉,魚],而不是我所期望的只是[魚],雞肉將轉入檔案(歷史)。

所以問題是,你如何引用舊的數組值,以及如何給新值賦予一個數組,以便它會按照我預期的那樣更新,如上所述。

我記得在閱讀引擎蓋下的某個地方,它只是鏈接到一個屬性的一系列值。如果是這種情況,那麼這是否意味着我必須找到字符串的datomic id並更改它?如果不在新列表中,還必須將其刪除?

回答

0

如果你需要一個「最後一次贏取」風格一致的解決方案來替換一個特定實體的所有值以獲得一張牌的許多屬性,那麼最好的選擇是使用transaction function。您可以採取以下方法:

  1. 獲取所有匹配您想要收回所有值的實體+屬性的數據。
  2. 爲它們生成縮回。
  3. 創建加交易所有新值(例如,從傳遞的集合)
  4. 刪除任何衝突(例如,如果你有一個外接和結果相同EAV)
  5. 返回所產生的交易數據。
+0

我猜這會產生兩個交易。一個收回所有的價值,另一個收回他們的價值? 我去了另一個創建另一個名字空間的路線,那裏有數組。這樣我只需創建一個新的名稱空間並將ref更改爲新的名稱空間。我不知道這是更快還是更快。 – pompanoSlayer

+0

您正在通過查看兩個數據集合(您在那裏以及您想要在那裏存在什麼)來生成一個事務(「返回生成的事務數據」)。這就是說,我的步驟是冗長的,你可以在檢查後通過例如聲明差異。拉,這可能是一個更好的解決方案。 –

+0

看來,如果我要遵循實體和謂詞的Datomic模型,這將導致我的解決方案VS我的。當我在另一個實體中添加以幫助解決此問題時,它會變得模糊。 – pompanoSlayer

1

僅供參考,這些都是我目前使用這類任務的一般交易功能(從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。