我在搞清楚拉动API方面遇到了一些麻烦。我有两个位置实体。当我使用pull
时,我只会收到一个。
(ns some-ns.core
(:require [datomic.api :as d]))
(d/q '[:find ?e
:where [?e :location/name]]
db)
=> #{[17592186045535] [17592186045420]} ; two results
(d/q '[:find [(pull ?e [:db/id
:location/name])]
:where [?e :location/name]]
db)
=> [{:db/id 17592186045535, :location/name "Some Other Location"}] ; one result
我怀疑我可能正在使用不正确的拉动表达式,但我没有看到任何明显的错误。
答案 0 :(得分:3)
看起来我错过了...
。
(d/q '[:find [(pull ?e [:db/id
:location/name]) ...]
:where [?e :location/name]]
db)
=> [{:db/id 17592186045535, :location/name "Some Other Location"} {:db/id 17592186045420, :location/name "White House"}]
答案 1 :(得分:3)
在您提供的示例中,您正在使用"单元组"拉表达式周围的find specification,它只返回单个元组,而不管查询匹配的实体数量。如果您在find中指定了标量返回,即使用.
,则会遇到同样的问题。
(1)最直接的解决方法是删除查找规范(这与原始查询的形式相符):
(d/q '[:find (pull ?e [:db/id :location/name])
:where [?e :location/name]]
db)
(2)您也可以像在自己的答案中一样,在find中指定一个集合:
(d/q '[:find [(pull ?e [:db/id :location/name]) ...]
:where [?e :location/name]]
db)
主要区别在于(1)将返回一组嵌套地图,而(2)将返回地图矢量。
答案 2 :(得分:1)
为避免像这样的细微错误,您可以尝试the Tupelo Datomic library.
Tupelo Datomic没有使用像“......”,“[]”等混淆的符号,而是将查询语法分成四个不同的函数。以下是一个示例用法:
StepExecution
; If you want just a single attribute as output, you can get a set of values (rather than a set of
; tuples) using td/query-set. As usual, any duplicate values will be discarded.
(let [names (td/query-set :let [$ (live-db)]
:find [?name] ; <- a single attr-val output allows use of td/query-set
:where [ [?eid :person/name ?name] ] )
cities (td/query-set :let [$ (live-db)]
:find [?loc] ; <- a single attr-val output allows use of td/query-set
:where [ [?eid :location ?loc] ] )
]
(is (= names #{"Dr No" "James Bond" "M"} )) ; all names are present, since unique
(is (= cities #{"Caribbean" "London"} ))) ; duplicate "London" discarded
API is also supported,如果该格式更适合您的问题。享受!