Datomic Pull API仅检索一个实体

时间:2015-07-12 23:45:46

标签: clojure datomic

我在搞清楚拉动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

我怀疑我可能正在使用不正确的拉动表达式,但我没有看到任何明显的错误。

3 个答案:

答案 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,如果该格式更适合您的问题。享受!