Datomic 新手问题 - 当一个事实发生变化时对相关事实进行建模

Datomic newbie question - modelling related facts when one fact changes

如果我有一个客户实体,并且他们在时间 t1 从具有以下事实的地址移动:

到新地址和时间 t2,这些事实:

如何避免 t2 之后的地址看起来像:

我能想到的选项:

  1. 在 t2 断言 address_line_2 = "" 以重置或清除它。
  2. 将地址作为它自己的实体指向一个新地址实体,该实体只有两个事实:address_line_1 = "1600 Pennsylvania Ave NW" 和 city = "Washington DC" 断言。
  3. 在 t2 断言一个新事实,例如 "moved_house" = true 来表示他们的地址不同。

我的想法:

任何其他人对此的想法将不胜感激:)

您可以使用选项 2 作为组件实体。

https://support.cognitect.com/hc/en-us/articles/215581418-Component-Attributes?mobile_site=true

这是一个示例:

;; schema
;;
(d/transact conn [{:db/ident      :client/address
                  :db/cardinality :db.cardinality/one
                  :db/valueType   :db.type/ref
                  :db/isComponent true}
                  {:db/ident      :address/line1
                  :db/valueType   :db.type/string
                  :db/cardinality :db.cardinality/one}
                  {:db/ident      :address/country
                  :db/valueType   :db.type/string
                  :db/cardinality :db.cardinality/one}])

;; create a new client with address - 1 Main Street
;;
(d/transact conn [{:db/id         (d/tempid :db.part/user -1)
                  :client/address {:address/line1   "1 Main Street"
                                   :address/country "USA"}}])

;; datomic will return you two entity id.  One is for :client/address
;; and another one for :address/line1 and :address/country
;;
(d/q '[:find (pull ?e [*])
      :where [?e :client/address]]
    (d/db conn))
;; => [[{:db/id 17592186045418, :client/address {:db/id 17592186045419, :address/line1 "1 Main Street", :address/country "USA"}}]]

;; now update its client address to 9 Kings Road.
;;
(d/transact conn [{:db/id          17592186045418
                  :client/address {:address/line1 "9 Kings Road"}}])

;; 17592186045418 will then have a :client/address 
;; pointing to a new entity with the new address
;;
(d/q '[:find (pull ?e [*])
      :where [?e :client/address]]
    (d/db conn))
;; => [[{:db/id 17592186045418, :client/address {:db/id 17592186045421, :address/line1 "9 Kings Road"}}]]