我尝试使用下面的代码查找所有用户创建的属性,并返回许多其他默认属性,例如db/unique
和fressian/tag
。
我想得到一个没有它们的集合,所以我想知道是否有更好的方法来获取它而不是通过它们的前缀过滤掉属性。
由于
(q {:find '[?ident]
:where '[[:db.part/db :db.install/attribute ?p]
[?p :db/ident ?ident]]} db)
或
(filter (partial instance? datomic.db.Attribute)
(:elements (p/db)))
答案 0 :(得分:6)
执行此操作的一种方法是白名单/黑名单列出要过滤或包含的名称空间。请注意,某些Datomic的内置属性和用户属性之间存在无差异。您可以在任何系统命名空间中自由创建属性,例如db.type
但当然你不应该这样做。
话虽如此,只有少数命名空间用于系统属性,因此您可以简单地过滤掉那些已知的命名空间。 e.g。
(def system-ns #{"db" "db.type" "db.install" "db.part"
"db.lang" "fressian" "db.unique" "db.excise"
"db.cardinality" "db.fn"})
(d/q '[:find ?e ?ident
:in $ ?system-ns
:where
[?e :db/ident ?ident]
[(namespace ?ident) ?ns]
[((comp not contains?) ?system-ns ?ns)]]
(d/db conn) system-ns)
答案 1 :(得分:0)
这就是我最终这样做的方式:
(defn get-user-schema [db]
(->> (d/q '[:find ?e
:where
[?e :db/ident ?ident]
[(namespace ?ident) ?ns]
(not (or [(contains? #{"db" "fressian"} ?ns)]
[(.startsWith ?ns "db.")]))]
db)
(map #(->> % first (d/entity db) d/touch (into {})))))
答案 2 :(得分:0)
显示用户定义的属性:
(clojure.pprint/print-table (->> (d/pull db '{:eid 0 :selector [{:db.install/attribute [*]}]})
:db.install/attribute
(remove (fn [m] (or (clojure.string/starts-with? (namespace (:db/ident m)) "db") (clojure.string/starts-with? (namespace (:db/ident m)) "fressian"))))
(map #(update % :db/valueType :db/ident))
(map #(update % :db/cardinality :db/ident))
(sort-by :db/ident)))
(改编自此处的 get-schema
函数:Datomicion-starter - GitHub)
输出:
| :db/id | :db/ident | :db/valueType | :db/cardinality |
|--------+--------------+------------------+----------------------|
| 74 | :inv/color | :db.type/keyword | :db.cardinality/one |
| 80 | :inv/count | :db.type/long | :db.cardinality/one |
| 75 | :inv/size | :db.type/keyword | :db.cardinality/one |
| 73 | :inv/sku | :db.type/string | :db.cardinality/one |
| 76 | :inv/type | :db.type/keyword | :db.cardinality/one |
| 79 | :item/count | :db.type/long | :db.cardinality/one |
| 78 | :item/id | :db.type/ref | :db.cardinality/one |
| 77 | :order/items | :db.type/ref | :db.cardinality/many |