查找缺少特定属性的所有实体
Find all entities that are missing a particular attribute
在我的模式中,我有属性 :base/type
,它应该存在于每个创建的实体中。为了检查这是否确实如此,我试图找到它丢失的实体:
[:find [?entities ...]
:in $ :where
[(missing? $ ?entities :base/type)]]
不幸的是,这让我回来了:
Execution error (Exceptions$IllegalArgumentExceptionInfo) at datomic.error/arg (error.clj:57).
:db.error/insufficient-binding [?entities] not bound in expression clause: [(missing? $ ?entities :base/type)]
应该如何构造这个查询?
这是因为您的查询过于笼统。如果使用查询 API,则 where 语句中至少需要一个肯定子句。不过,您可以访问原始索引来获取结果。如果您有足够的 RAM,您可以:
(def snapshot (d/db connection)) ; your db snapshot
(def all-datoms (d/datoms snapshot :eavt))
(def base-type-id (:db/id (d/entity snapshot :base/type))
(def entities (group-by #(.e %) all-datoms))
(def entities-without-base-type (map
(comp #(into {} %) (partial d/entity snapshot) first)
(filter (fn [[k l]]
(empty? (filter #(= base-type-id (.a %))
l)))
entities)))
(def only-relevant-entities (filter #(not (or (:db/ident %) (:db/txInstant %))) entities-without-base-type))
only-relevant-entities
最后一个过滤器是去除属性定义和事务(它们也作为数据存储在数据库中!)。
如果你有太多的实体,你可以使用异步原子 API。
使用 ::singer/songs
作为示例属性,查询的方法如下:
[:find [?entities ...]
:in $ :where
[?entities ::singer/songs ?s]
[(missing? $ ?entities :base/type)]]
不幸的是(在我的回答中)在整个数据库被覆盖之前,将需要许多这样的查询。所以另一个查询 ::song/composers
,等等...
在我的模式中,我有属性 :base/type
,它应该存在于每个创建的实体中。为了检查这是否确实如此,我试图找到它丢失的实体:
[:find [?entities ...]
:in $ :where
[(missing? $ ?entities :base/type)]]
不幸的是,这让我回来了:
Execution error (Exceptions$IllegalArgumentExceptionInfo) at datomic.error/arg (error.clj:57).
:db.error/insufficient-binding [?entities] not bound in expression clause: [(missing? $ ?entities :base/type)]
应该如何构造这个查询?
这是因为您的查询过于笼统。如果使用查询 API,则 where 语句中至少需要一个肯定子句。不过,您可以访问原始索引来获取结果。如果您有足够的 RAM,您可以:
(def snapshot (d/db connection)) ; your db snapshot
(def all-datoms (d/datoms snapshot :eavt))
(def base-type-id (:db/id (d/entity snapshot :base/type))
(def entities (group-by #(.e %) all-datoms))
(def entities-without-base-type (map
(comp #(into {} %) (partial d/entity snapshot) first)
(filter (fn [[k l]]
(empty? (filter #(= base-type-id (.a %))
l)))
entities)))
(def only-relevant-entities (filter #(not (or (:db/ident %) (:db/txInstant %))) entities-without-base-type))
only-relevant-entities
最后一个过滤器是去除属性定义和事务(它们也作为数据存储在数据库中!)。
如果你有太多的实体,你可以使用异步原子 API。
使用 ::singer/songs
作为示例属性,查询的方法如下:
[:find [?entities ...]
:in $ :where
[?entities ::singer/songs ?s]
[(missing? $ ?entities :base/type)]]
不幸的是(在我的回答中)在整个数据库被覆盖之前,将需要许多这样的查询。所以另一个查询 ::song/composers
,等等...