Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 从Datomic检索最近的实体_Clojure_Datomic - Fatal编程技术网

Clojure 从Datomic检索最近的实体

Clojure 从Datomic检索最近的实体,clojure,datomic,Clojure,Datomic,我对实体及其时间戳感兴趣。本质上,我想要一个按时间排序的实体列表 为此,我编写了以下函数: (defn return-posts "grabs all posts from Datomic" [] (d/q '[:find ?title ?body ?slug :where [?e :post/title ?title] [?e :post/slug ?slug] [?e :post/body ?body]] (

我对实体及其时间戳感兴趣。本质上,我想要一个按时间排序的实体列表

为此,我编写了以下函数:

(defn return-posts
  "grabs all posts from Datomic"
  []
  (d/q '[:find ?title ?body ?slug
         :where
         [?e :post/title ?title]
         [?e :post/slug ?slug]
         [?e :post/body ?body]] (d/db connection)))

(defn get-postid-from-slug
  [slug]
  (d/q '[:find ?e
         :in $ ?slug
         :where [?e :post/slug ?slug]] (d/db connection) slug))

(defn get-post-timestamp
  "given an entid, returns the most recent timestamp"
  [entid]
  (->
   (d/q '[:find ?ts
          :in $ ?e
          :where
          [?e _ _ _]
          [?e :db/txInstant ?ts]] (d/db connection) entid)
   (sort)
   (reverse)
   (first)))
我觉得这一定是源于无知的黑客行为


是否有更精通惯用达托米用法的人加入并升级我的范例?

没有比遍历事务更优雅的方法了。这就是为什么我更喜欢时间戳有一个单独的域特定属性,而不是依赖Datomic的事务时间戳。一个需要合并的例子是:假设您有一个wiki,并且希望合并两个wiki页面。在这种情况下,您可能希望自己控制时间戳,而不是使用事务中的时间戳

我希望在处创建属性
:并在
处更改属性
。当我交易新实体时:

[[:db/add tempid :post/slug "..."]
 [:db/add tempid :post/title "A title"]
 [:db/add tempid :created-at (java.util.Date.)]
 [:db/add tempid :changed-at (java.util.Date.)]]
然后更新:

[[:db/add post-eid :post/title "An updated title"]
 [:db/add post-eid :changed-at (java.util.Date.)]]
这样,我所要做的就是读取实体的:created at属性,该属性将准备就绪并在索引中等待

(defmacro find-one-entity
  "Returns entity when query matches, otherwise nil"
  [q db & args]
  `(when-let [eid# (ffirst (d/q ~q ~db ~@args))]
     (d/entity ~db eid#)))

(defn find-post-by-slug
  [db slug]
  (find-one-entity
    '[:find ?e
      :in $ ?slug
      :where
      [?e :post/slug ?slug]]
    db
    slug))

;; Get timestamp
(:created-at (find-post-by-slug db "my-post-slug"))

我对向数据库中添加额外时间戳的想法感到困扰,该数据库名义上将时间理解为一级原则,因此(经过一个晚上对所述方法的深思熟虑后)发展了以下功能:

(defn return-posts
  "grabs all posts from Datomic"
  [uri]
  (d/q '[:find ?title ?body ?slug ?ts
         :where
         [?e :post/title ?title ?tx]
         [?e :post/slug ?slug]
         [?e :post/body ?body]
         [?tx :db/txInstant ?ts]] (d/db (d/connect uri))))
在数据日志中,省略与事务ID本身的绑定是惯用做法,因为我们通常不在乎。在这种情况下,我们非常关心,用August Lileaas的话说,我们希望“遍历事务”(在某些情况下,我们需要创建后的时间,但对于这个应用程序,事务时间足以对实体进行排序)

这种方法的一个显著缺点是,最近编辑的条目将在列表中增加。为了达到这一目的,我将不得不在以后做一些事情,以便让他们在博客标准帖子历史的Datomic中“首次亮相”

总结如下:
我已经根据“post”实体ID绑定了事务实体ID,然后使用此函数查找事务时间戳,以便以后进行排序。

值得注意的是,好的,这使您可以立即为实体声明:post/title的当前值,而不是实体最后一次作为事务主题时的值。如果数据不适合内存,该怎么办?例如,您希望获得(比如)5个最新实体,而不关心其他实体。