2013-09-28 2 views
13

엔티티와 타임 스탬프에 관심이 있습니다. 기본적으로 엔티티의 시간순으로 정렬 된 목록이 필요합니다. 이를 위해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]] (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 사용에 익숙한 사람이 내 패러다임을 선택하고 업그레이드합니까?

답변

7

내가 명목상 (Ulrik Sandberg에 의해 설명 된 방법에 궁리의 밤 이후) 그래서 일류 원칙으로 시간과 이해 데이터베이스에 추가 타임 스탬프를 추가하는 아이디어에 의해 방해되었다 다음과 같은 기능을 진화 :

(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의 말에 따르면, "트랜잭션을 가로 지르고 싶다"(포스트 생성 시간을 원할 수있는 상황이 있지만,이 애플리케이션의 경우 엔티티 주문 엔티티).

이 방법의 가장 큰 단점은 최근에 편집 된 항목이 목록에 올라와 있다는 것입니다. 이를 위해 나중에 Blog-standard post history에 대한 Datomic의 "첫 등장"을 위해 뭔가를해야 할 것입니다.

요약 할 내용 : "게시"엔티티 ID 당 트랜잭션 엔티티 ID를 바인딩 한 다음 나중에 정렬 할 수 있도록이 함수로 트랜잭션 타임 스탬프를 조회했습니다.

+2

AFAIK는 게시물/제목이 엔티티에 대해 어설 션되었으며 엔티티가 마지막으로 거래의 주제가 아닌 순간의 현재 값을 제공한다는 점에 유의할 가치가 있습니다. – spieden

2

트랜잭션을 트래버스하는 것보다 실제로 이렇게 우아한 방법은 없습니다. 이것이 Datomic의 트랜잭션 타임 스탬프에 의존하는 대신 시간 소인에 대해 별도의 도메인 특정 속성을 갖는 것을 선호하는 이유입니다. 이것이 필요한 곳의 한 예가 병합입니다. 위키가 있고 두 개의 위키 페이지를 병합한다고합시다. 이 경우 사용자는 타임 스탬프를 직접 제어하고 트랜잭션의 타임 스탬프를 사용하지 않을 것입니다.

저는 :created-at:changed-at의 속성을 갖고 있습니다.

[[: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.)]] 

내가 할 일은 읽어 것입니다 그 방법을 : 준비가 될 것입니다 엔티티의 속성-에서 생성 색인에서 대기 중입니다.

(defmacro find-one-entity 
    "Returns entity when query matches, otherwise nil" 
    [q db & args] 
    `(when-let [eid# (ffirst (d/q ~q ~db [email protected]))] 
    (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"))