Clojure 如何列出所有用户创建的属性?
我尝试用下面的代码查找所有用户创建的属性,它返回许多其他默认属性,如Clojure 如何列出所有用户创建的属性?,clojure,datomic,Clojure,Datomic,我尝试用下面的代码查找所有用户创建的属性,它返回许多其他默认属性,如db/unique和fressian/tag 我想得到一个没有它们的集合,所以我想知道是否有比通过前缀过滤掉属性更好的方法 谢谢 (q {:find '[?ident] :where '[[:db.part/db :db.install/attribute ?p] [?p :db/ident ?ident]]} db) 或 一种方法是将要筛选或包含的名称空间以白/黑的方式列出。注意,Datom
db/unique
和fressian/tag
我想得到一个没有它们的集合,所以我想知道是否有比通过前缀过滤掉属性更好的方法
谢谢
(q {:find '[?ident]
:where '[[:db.part/db :db.install/attribute ?p]
[?p :db/ident ?ident]]} db)
或
一种方法是将要筛选或包含的名称空间以白/黑的方式列出。注意,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)
我就是这样做的:
(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 {})))))
显示用户定义的属性:
| :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 |
(clojure.pprint/print-table(->>(d/pull db'{:eid 0:selector[{:db.install/attribute[*]})
:db.install/attribute
(删除(fn[m](或(clojure.string/starts-with?(名称空间(:db/ident m))“db”)(clojure.string/starts-with?(名称空间(:db/ident m))“fressian”))
(映射#(更新%:db/valueType:db/ident))
(映射#(更新%:db/基数:db/ident))
(排序依据:db/ident)))
(改编自此处的get schema
函数:)
输出:
| :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 |
我认为
systemns
已经扩展到至少包括“db.alter”“db.bootstrap”“db.sys”
为什么不过滤掉所有的db.*名称空间?