如何构建一个引用可变数量实体的事务?

时间:2014-08-26 19:02:45

标签: clojure datomic

我正在进入datomic并仍然没有理解它。如何构建一个引用可变数量实体的事务?

例如,这会创建一个具有子实体的事务和一个具有引用新子实体的子属性的族实体:

(defn insert-child [id child]
  {:db/id #db/id id
   :child/first-name (:first-name child)
   :child/middle-name (:middle-name child)
   :child/last-name (:last-name child)
   :child/date-of-birth {:date-of-birth child}})

(defn insert-family [id]
  (let [child-id #db/id[:db.part/user]]
    (vector
     (insert-child child-id
                   {:first-name "Richard"
                    :middle-name "M"
                    :last-name "Stallman"})
     {:db/id id
      :family/child child-id})))

(insert-family #db/id[:db.part/user])
=> [{:db/id #db/id[:db.part/user -1000012], 
     :child/first-name "Richard", 
     :child/middle-name "M", 
     :child/last-name "Stallman", 
     :child/date-of-birth nil} 
    {:db/id #db/id[:db.part/user -1000013], 
     :family/child #db/id[:db.part/user -1000012]}]

注意我使用了let child-id。我不知道如何写这个,以便我可以映射insert-child,同时拥有一个引用每个实体的家庭实体。

我考虑过使用iterate而不是#db/id[:db.part/user]以及子项数量,然后映射iterate的结果和子项向量。似乎有点复杂,#db/id[:db.part/user]不是一个迭代开始的函数。

1 个答案:

答案 0 :(得分:3)

不应使用适用于EDN文件和数据文字的宏形式#db / id [:db.part / user],而应使用d/tempid

你可以这样做(使用简化的子实体):

(ns family-tx
    (:require [datomic.api :refer [q db] :as d]))

(def uri "datomic:mem://testfamily")
(d/delete-database uri)
(d/create-database uri)
(def conn (d/connect uri))

(def schema [
              {:db/id (d/tempid :db.part/db)
               :db/ident :first-name
               :db/valueType :db.type/string
               :db/cardinality :db.cardinality/one
               :db.install/_attribute :db.part/db}
              {:db/id (d/tempid :db.part/db)
               :db/ident :last-name
               :db/valueType :db.type/string
               :db/cardinality :db.cardinality/one
               :db.install/_attribute :db.part/db}
              {:db/id (d/tempid :db.part/db)
               :db/ident :family/child
               :db/valueType :db.type/ref
               :db/cardinality :db.cardinality/many
               :db.install/_attribute :db.part/db}
            ])
@(d/transact conn schema)


(defn make-family-tx [kids]
  (let [kids-tx (map #(into {:db/id (d/tempid :db.part/user)} %) kids)
        kids-id (map :db/id kids-tx)]
          (conj kids-tx {:db/id (d/tempid :db.part/user)
                         :family/child kids-id})))


(def kids [{:first-name "Billy" :last-name "Bob"}
           {:first-name "Jim" :last-name "Beau"}
           {:first-name "Junior" :last-name "Bacon"}])

@(d/transact conn (make-family-tx kids))

Transactions文档中也讨论了一些策略(请参阅“识别实体”部分)。