10

mbrainz示例数据中,:artist/type 是一个枚举。是否可以从 :db/ident 中提取枚举值并使用拉语法将其关联为 :artist/type 键的值?

这是我能得到的最接近的:

[:find (pull ?e [:artist/name {:artist/type [:db/ident]}])
 :where
 [?e :artist/name "Ray Charles"]
]

;;=> [[{:artist/name "Ray Charles", :artist/type {:db/ident :artist.type/person}}]]

是否可以使用拉语法将结果重塑成这样的东西?

;;=> [[{:artist/name "Ray Charles", :artist/type :artist.type/person}]]
4

3 回答 3

1

很容易做到postwalk

对于任何拉出的 :db/ident,您都可以使用此函数进行转换

(defn flatten-ident [coll]
  (clojure.walk/postwalk
   (fn [item] (get item :db/ident item)) coll))
于 2021-02-25T15:16:07.223 回答
1

您可以对 pull 表达式返回的结果使用 spectre:

(->> pull-result                                                                                     
     (sp/transform (sp/walker :db/ident) :db/ident))

:db/ident为每个具有该键的地图提取键的值。

于 2020-10-23T08:55:33.237 回答
1

我认为您无法按照您所寻求的方式使用 Pull API 来做到这一点。您可能会发现使用Tupelo Datomic库更容易:

(require '[tupelo.datomic :as td]
         '[tupelo.core :refer [spyx]] )
(let [x1      (td/query-scalar  :let     [$ db-val]
                                :find    [ ?e ]
                                :where   [ [?e :artist/name "Ray Charles"] ] )
      x2      (td/entity-map db-val x1)
     ]
  (spyx x1)
  (spyx x2)
)

结果是:

x1 => 17592186049074

x2 => {:artist/sortName "Charles, Ray", :artist/name "Ray Charles", :artist/type :artist.type/person, :artist/country :country/US, :artist/gid #uuid " 2ce02909-598b-44ef-a456-151ba0a3bd70", :artist/startDay 23, :artist/endDay 10, :artist/startYear 1930, :artist/endMonth 6, :artist/endYear 2004, :artist/startMonth 9, :artist/性别 :artist.gender/male}

因此 :artist/type 已经转换为 :db/ident 值,您可以将其从地图中拉出。

于 2015-08-05T16:48:04.303 回答