Datomic вопрос новичка - моделирование связанных фактов, когда один факт изменяется - PullRequest
0 голосов
/ 22 января 2019

Если у меня есть клиентский объект, и он переходит с адреса в момент времени t1, который имеет эти факты:

  • address_line_1 = "10 Даунинг Ст"
  • address_line_2 = "Вестминстер"
  • city = "Лондон"

по новому адресу и времени t2 с этими фактами:

  • address_line_1 = "1600 Pennsylvania Ave NW"
  • city = "Вашингтон, округ Колумбия"

Как избежать появления адреса в момент времени t2 следующим образом:

  • address_line_1 = "1600 Pennsylvania Ave NW"
  • address_line_2 = "Вестминстер"
  • city = "Вашингтон, округ Колумбия"

Варианты, которые я могу придумать:

  1. утверждают факт в момент времени t2that address_line_2 = "", чтобы сбросить или очистить его.
  2. имеет адрес, так как его собственная сущность указывает на новую адресную сущность, которая имеет только два факта: address_line_1 = "1600 Pennsylvania Ave NW" и city = "Вашингтон, округ Колумбия "утверждал на этом.
  3. утверждают новый факт в t2 как" двинутый дом "= истина, чтобы выразитьс учетом того, что их адрес другой.

Мои мысли:

  • Вариант 1, кажется, полагается на "знание" того, что было установлено ранее за все время, которое может больше не быть правдойтак что вы можете их убрать.
  • Вариант 2 кажется лучшим - но это означает, что определяется больше сеток, чем я ожидал.
  • Вариант 3 кажется противным!

Чужие мысли по этому поводу будут высоко оценены:)

1 Ответ

0 голосов
/ 23 января 2019

Вы можете использовать вариант 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"}}]]
...