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

标签 clojure datomic

我有这个简单的模式和数据:

(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 和价格时,它会给我更高价的 Boot :

(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 没有以任何方式绑定(bind)到 (min ?p) 表达式,所以它没有定义你的内容会到达那里,超越某种产品实体 ID。

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

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

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

关于clojure - 在结果元组中检索实体 ID 时,Datomic 未返回正确的 "min"结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63779916/

相关文章:

recursion - 用于计算组合的尾递归 Clojure 函数

java - 从 Clojure 捕获 riak-java-client 的特定异常

multithreading - 在 Clojure 的多线程程序中初始化资源的正确方法是什么

database - 如何防止事务违反 Datomic 中的应用程序不变量

clojure - 合并原子查询结果中的某些属性

datomic - 如何查询特定分区中所有 datomic 的 datomic?

ssh - 杰普森 : SSH issue

clojure - 响铃响应下载index.html而不是渲染它

clojure - 如何帮助Clojure理解0是最小的自然数?

clojure - n 元谓词 Datomic (n != 2) 可能吗?