在结果元组中检索实体 ID 时,Datomic 未返回正确的 "min" 结果

Datomic not returning the correct "min" result when retrieving entity ID in result tuple

我有这个简单的架构和数据:

(def product-offer-schema
  [{:db/ident :product-offer/product
    :db/valueType :db.type/ref
    :db/cardinality :db.cardinality/one}
   {:db/ident :product-offer/vendor
    :db/valueType :db.type/ref
    :db/cardinality :db.cardinality/one}
   {:db/ident :product-offer/price
    :db/valueType :db.type/long
    :db/cardinality :db.cardinality/one}
   {:db/ident :product-offer/stock-quantity
    :db/valueType :db.type/long
    :db/cardinality :db.cardinality/one}
  ])
(d/transact conn product-offer-schema)

(d/transact conn
  [{:db/ident :vendor/Alice}
   {:db/ident :vendor/Bob}
   {:db/ident :product/BunnyBoots}
   {:db/ident :product/Gum}
  ])
(d/transact conn
  [{:product-offer/vendor  :vendor/Alice
    :product-offer/product :product/BunnyBoots
    :product-offer/price   9981 ;; .81
    :product-offer/stock-quantity 78
   }

   {:product-offer/vendor  :vendor/Alice
    :product-offer/product :product/Gum
    :product-offer/price   200 ;; .00
    :product-offer/stock-quantity 500
   }

   {:product-offer/vendor  :vendor/Bob
    :product-offer/product :product/BunnyBoots
    :product-offer/price   9000 ;; .00
    :product-offer/stock-quantity 15
   }
  ])

当我检索最便宜的兔子靴时,仅检索价格,我得到预期结果 (9000):

(def cheapest-boots-q '[:find (min ?p) .
                        :where
                        [?e :product-offer/product :product/BunnyBoots]
                        [?e :product-offer/price ?p]
                       ])
(d/q cheapest-boots-q db)
;; => 9000

然而,当我想获得实体 ID 和价格时,它给了我更高价的靴子:

(def db (d/db conn))
(def cheapest-boots-q '[:find [?e (min ?p)]
                        :where
                        [?e :product-offer/product :product/BunnyBoots]
                        [?e :product-offer/price ?p]
                       ])
(d/q cheapest-boots-q db)
;; => [17592186045423 9981]

我尝试添加 :with 但这给了我一个错误:

(def cheapest-boots-q '[:find [?e (min ?p)]
                        :with ?e
                        :where
                        [?e :product-offer/product :product/BunnyBoots]
                        [?e :product-offer/price ?p]
                       ])
(d/q cheapest-boots-q db)
;; => =>  Execution error (ArrayIndexOutOfBoundsException) at datomic.datalog/fn$project (datalog.clj:503).

我做错了什么?

正如评论者指出的那样,?e 不以任何方式绑定到 (min ?p) 表达式,因此除了产品实体 ID 之外,它没有定义您将到达那里的内容某种形式。

您真正想要做的是以某种方式将这些值统一为查询的一部分,而不是对结果执行聚合,例如:

(d/q '[:find [?e ?p]
       :where
       [?e :product-offer/product :product/BunnyBoots]
       [?e :product-offer/price ?p]
       [(min ?p)]] 
     db)

你可以看到 min 子句是查询的一部分,因此将参与结果的统一,给你你想要的。