Datomic在结果元组中检索实体ID时未返回正确的“最小”结果

问题描述

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

(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 ;; $99.81
    :product-offer/stock-quantity 78
   }

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

   {:product-offer/vendor  :vendor/Bob
    :product-offer/product :product/BunnyBoots
    :product-offer/price   9000 ;; $90.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子句是查询的一部分,因此将参与结果的统一,从而为您提供所需的内容。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...