Как получить все значения атрибута ref?

Я touch и entity получаю множество идентификаторов сущностей. Я хочу, чтобы все значения атрибутов вместо идентификаторов сохранялись при сохранении вложенной структуры.

(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 "[email protected]",
    :db/id 17592186045429}

Думал об использовании чего-то вроде простого прикосновения ко всем идентификаторам сущностей, но кажется, что сложность возрастает, если я хочу их все:

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

Не уверен, что такое идиоматический подход: найти способ сделать это больше через запрашивающую сторону или через clojure.


person deadghost    schedule 05.09.2014    source источник


Ответы (2)


Идиоматический способ сделать это в Datomic — объявить компоненты в вашей схеме. touch рекурсивно коснется всех атрибутов объекта, включая любые компоненты.

person laurie    schedule 22.10.2014

Возможно, вы захотите использовать для этой цели Datomic Pull API. Он может рекурсивно возвращать пары атрибут/значение для всех подсущностей, которые пользователь определяет как "компонент". Пример:

  (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}]}
      ...]}]}

Вы также можете использовать 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"   } ] ] )))
person Alan Thompson    schedule 03.09.2015