在Datomic中查找具有特定属性的最旧和最新实体的日期?

时间:2016-08-27 11:44:23

标签: clojure datomic

让我们说一个像这样的Datomic架构:

{:db/id                 #db/id[:db.part/db]
  :db/ident              :app/createdAt
  :db/doc                "The date and time when the entity was created (not necessarily the same as tx time)"
  :db/valueType          :db.type/instant
  :db/cardinality        :db.cardinality/one
  :db.install/_attribute :db.part/db}
  {:db/id                 #db/id[:db.part/db]
  :db/ident              :app/type
  :db/doc                "The type of the entity"
  :db/valueType          :db.type/string
  :db/cardinality        :db.cardinality/one
  :db.install/_attribute :db.part/db}    

在应用程序的生命周期中创建了多个此类实体。我有兴趣找到特定类型(:app/createdAt)最旧和最新实体的:app/type即时/日期,比如" type1"。这样的查询在Datomic中会是什么样子?

1 个答案:

答案 0 :(得分:2)

一种简单的方法是使用Datalog查询:

[:find (min ?c) (max ?c) :in $ ?type :where
 [?e :app/type ?type]
 [?e :app/createdAt ?c]]

性能考虑因素

从Datomic 0.9.5385开始,Datalog引擎将对匹配[?e :app/type ?type]子句的实体执行完整扫描;如果有很多这样的实体,这可能导致许多网络往返存储,对等端的高资源消耗和显着的延迟。

幸运的是,您可以使用Datomic的Optimization of Range Predicates来限制查询扫描的数据的数量。例如,要计算最大创建日期,如果您知道在2016年8月之后创建了至少一个此类实体,则可以调用:

(d/q '[:find (max ?c) . :in $ ?type ?lower-bound :where
       [?e :app/createdAt ?c]
       [(>= ?c ?lower-bound)]
       [?e :app/type ?type]]
  db #inst "2016-08")

请注意,Datalog子句的顺序很重要。

免责声明:我不了解Datomic的源代码,只是从个人实验中推断出上述断言。