如何获取所有ref属性值?

时间:2014-09-05 00:24:16

标签: clojure datomic

touchentity并获得许多实体ID。我想要所有属性值而不是id,同时保持嵌套结构。

(d/touch (d/entity (get-db) (ffirst (find-all-families))))
=> {:family/parent #{{:db/id 17592186045423}
                     {:db/id 17592186045424}
                     {:db/id 17592186045426}
                     {:db/id 17592186045427}},
    :family/child #{{:db/id 17592186045420}
                    {:db/id 17592186045421}},
    :family/address {:db/id 17592186045428},
    :family/email "someemail@gmail.com",
    :db/id 17592186045429}

考虑使用简单地触及所有实体ID的东西,但如果我想要所有实体ID,似乎复杂性会增加:

(map d/touch (:family/parent (d/touch (d/entity (get-db) (ffirst (find-all-families))))))

不确定惯用法是什么:通过查询方面或通过clojure找到更多方法。

2 个答案:

答案 0 :(得分:0)

在Datomic中执行此操作的惯用方法是在架构中声明组件。 touch将触及实体的所有属性,包括递归的任何组件

答案 1 :(得分:0)

您可能希望将the Datomic Pull API用于此目的。它可以递归地返回用户指定为“组件”的所有子实体的attr / value对。一个例子:

  (def dark-side-of-the-moon [:release/gid #uuid "24824319-9bb8-3d1e-a2c5-b8b864dafd1b"])

  (d/pull db [:release/media] dark-side-of-the-moon)

  ; result 
  {:release/media
   [{:db/id 17592186121277,
     :medium/format {:db/id 17592186045741},
     :medium/position 1,
     :medium/trackCount 10,
     :medium/tracks
     [{:db/id 17592186121278,
       :track/duration 68346,
       :track/name "Speak to Me",
       :track/position 1,
       :track/artists [{:db/id 17592186046909}]}
      {:db/id 17592186121279,
       :track/duration 168720,
       :track/name "Breathe",
       :track/position 2,
       :track/artists [{:db/id 17592186046909}]}
      {:db/id 17592186121280,
       :track/duration 230600,
       :track/name "On the Run",
       :track/position 3,
       :track/artists [{:db/id 17592186046909}]}
      ...]}]}

你也可以使用the Tupelo Datomic Pull API,我认为这更好。举个例子:

  ; If you wish to retain duplicate results on output, you must use td/query-pull and the Datomic
  ; Pull API to return a list of results (instead of a set).
  (let [result-pull     (td/query-pull  :let    [$ (live-db)]                 ; $ is the implicit db name
                                        :find   [ (pull ?eid [:location]) ]   ; output :location for each ?eid found
                                        :where  [ [?eid :location] ] )        ; find any ?eid with a :location attr
        result-sort     (sort-by #(-> % first :location) result-pull)
  ]
    (is (s/validate [ts/TupleMap] result-pull))    ; a list of tuples of maps
    (is (= result-sort  [ [ {:location "Caribbean"} ]
                          [ {:location "London"   } ]
                          [ {:location "London"   } ] ] )))