我正在使用atomic Ions开发一个应用程序。在我的模式中,我使用复合元组来保证唯一性:书架上有书,而且书架+书的组合必须是唯一的。这是我的schema:
{:db/ident :shelf/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/value
:db/doc "A shelf is a grouping of books"}
;; Books
{:db/ident :book/shelf
:db/valueType :db.type/ref
:db/isComponent true
:db/cardinality :db.cardinality/one
:db/doc "Shelf this book belongs to"}
{:db/ident :book/id
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "The book identifier"}
;; Shelf + Book combination must be unique
{:db/ident :book/shelf+book
:db/valueType :db.type/tuple
:db/tupleAttrs [:book/shelf :book/id]
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity}
使用上面的模式,我可以执行以下拉/查询:
(d/pull db '[*] [:shelf/name "my-shelf"])
返回:{:db/id 74766790688854, :shelf/name "my-shelf"}
:
(d/q '[:find ?b ?id
:in $ ?shelf+book
:where [?b :book/shelf+book ?shelf+book]
[?b :book/id ?id]]
db [74766790688854 "book-1"])
返回:[[101155069755527 "book-1"]]
.
然而,我想使用一个查找ref来解析一个查询中的货架引用,以避免不得不做一个单独的查询来获得货架引用,如:
(d/q '[:find ?b ?id
:in $ ?shelf+book
:where
[?b :book/shelf+book ?shelf+book]
[?b :book/id ?id]]
db [[:shelf/name "my-shelf"] "book-1"])
但是上面返回的是[]
。是否有可能像上面的例子一样嵌套查找参考?
我从来没有尝试过复合元组,但这是它的工作原理:
您可以在正常查询中使用pull
API,如:
(d/q '[:find ?id (pull ?b [:shelf/name])
:in $ ?shelf+book
:where
[?b :book/shelf+book ?shelf+book]
[?b :book/id ?id]]
db [[:shelf/name "my-shelf"] "book-1"])
我经常在datomic中查询图。下面是我的应用程序中的一个例子:
(d/q '[:find
?id
(pull ?t [:db/ident])
(pull ?target-node [:my.graph.node/id
:my.graph.node/label])
:where
[?e :my.graph.edge/id ?id]
[?e :my.graph.edge/type ?t]
[?e :my.graph.edge/target ?target-node]]
db)
其中my.graph.edge/target
为:ref
,my.graph.edge/type
为enum的值。
一个示例输出是
[[#uuid"8e5fb3a4-1cac-40e2-ab8f-33352b6cabb3"
#:db{:ident :my.graph.edge.type/relationship}
#:my.graph.node{:label "Some node"}]
...]