Clojure 如何获取所有ref属性值?
我Clojure 如何获取所有ref属性值?,clojure,datomic,Clojure,Datomic,我触摸一个实体,并获得许多实体ID。我想要所有的属性值,而不是ID,同时保持嵌套结构 (d/touch (d/entity (get-db) (ffirst (find-all-families)))) => {:family/parent #{{:db/id 17592186045423} {:db/id 17592186045424} {:db/id 17592186045426}
触摸一个实体
,并获得许多实体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找到更多的方法。在Datomic中实现这一点的惯用方法是在模式中声明组件<代码>触摸
将递归触摸实体的所有属性,包括您可能希望用于此目的的任何组件。它可以递归地返回用户指定为“组件”的所有子实体的属性/值对。例如:
(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}]}
...]}]}
; 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" } ] ] )))
你也可以用这个,我觉得比较好。例如:
(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}]}
...]}]}
; 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" } ] ] )))