Datomic Pull API 只获取一个实体

Datomic Pull API only retrieves one entity

我在计算拉力时遇到了一些问题 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

我怀疑我可能使用了不正确的 pull 表达式,但我没有发现明显的错误。

看来我错过了 ...

(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"}]

在您提供的示例中,您在 pull 表达式周围使用了 "single tuple" find specification,无论与询问。如果您在查找中指定标量 return,即使用 ..

,您将 运行 陷入同样的​​问题

(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) 将 return 一组嵌套地图,而 (2) 将 return 地图向量。

为避免此类细微错误,您不妨尝试 the Tupelo Datomic library.

Tupelo Datomic 没有使用“...”、“[]”等令人困惑的符号,而是将查询语法拆分为四个不同的函数。这是一个示例用法:

  ; 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

pull API is also supported 如果该格式更适合您的问题。享受吧!