在Datomic中,如何获得对特定实体的值所做更改的时间轴视图?

zca*_*ate 12 clojure datomic

我正在按照教程http://www.datomic.com/company/resources/tutorial进行操作,但我想我错过了一个关于如何访问Datomic时间模型的难题.

如果我做了一系列的加法和缩进

;; DO a series of transactions 
;; (transact conn [:db/add entity-id attribute value0])

(use 'datomic.api)
(dir datomic.api)
(def conn (connect "datomic:dev://localhost:4334/demo"))

(transact conn '[:db/add 2000 :db/doc "Hello There"])
(q '[:find ?e ?n :where [?e :db/doc ?n] [(= 2000 ?e)]] (db conn))
; => <HashSet [[2000 "Hello There"]]>

(transact conn '[:db/add 2000 :db/doc "Hello There 1"])
(q '[:find ?e ?n :where [?e :db/doc ?n] [(= 2000 ?e)]] (db conn))
; => <HashSet [[2000 "Hello There 1"]]>

(transact conn '[:db/add 2000 :db/doc "Hello There 2"])
(q '[:find ?e ?n :where [?e :db/doc ?n] [(= 2000 ?e)]] (db conn))
; => <HashSet [[2000 "Hello There 2"]]>

(transact conn '[:db/add 2000 :db/doc "Hello There 3"])
(q '[:find ?e ?n :where [?e :db/doc ?n] [(= 2000 ?e)]] (db conn))
; => <HashSet [[2000 "Hello There 3"]]>
Run Code Online (Sandbox Code Playgroud)

如何在(实体2000属性:db/doc)上获得一系列值的更改?

我希望得到格式的东西

[ [Transaction Number, Time, Value] .... [Transaction Number, Time, Value]]
Run Code Online (Sandbox Code Playgroud)

例如:

[ [T1, "2012-March-16-9:30:12", "Hello There"] 
  .... 
  .... 
  .... 
  [T27, "2012-June-14-9:54:38", "Hello There 3"] ]
Run Code Online (Sandbox Code Playgroud)

它不是那么困难,但有很多:我不熟悉的db内部参数.

小智 9

看一下参考文献中的(history db)功能.

返回一个特殊的数据库,其中包含跨时间的所有断言和撤消.此特殊数据库可用于数据和索引范围调用和查询,但不能用于实体或调用.as-of和由于也支持边界.请注意,查询将获得所有的添加和撤消,可以通过第五个数据字段区分:added(对于add/assert为true)[eav tx added]

使用history你可以做这样的事情来获得你想要的数据:

datomic-test.core> (q '[:find ?tx ?tx-time ?v 
                        :in $ ?e ?a 
                        :where [?e ?a ?v ?tx _] 
                               [?tx :db/txInstant ?tx-time]] 
                      (d/history (db conn)) 
                      2000 
                      :db/doc)
#<HashSet [[13194139534315 #inst "2012-09-09T00:45:49.086-00:00" "Hello There"] [...]]>
Run Code Online (Sandbox Code Playgroud)

另外看看(tempid :db.part/user)获取ID而不是使用硬编码数字2000.