【问题标题】:Datomic aggregates usageDatomic 聚合使用情况
【发布时间】:2014-04-22 09:06:28
【问题描述】:

我想通过下一个查询找到年龄最小的人

(d/q '[:find ?name (min ?age)
         :in [[?name ?age]]]
       [["John" 20]
        ["Bill" 25]
        ["Jack" 20]
        ["Steve" 28]
        ["Andrew" 30]])

但结果是

[["Andrew" 30] ["Bill" 25] ["Jack" 20] ["John" 20] ["Steve" 28]]

怎么做?

【问题讨论】:

    标签: datomic datalog


    【解决方案1】:

    您可以使用子查询(从查询内部而不是外部查询调用),而不是将查询链接在一起:

    (d/q '[:find ?name ?mage
           :in $
           :where [(datomic.api/q '[:find (min ?age)
                                    :where [_ :age ?age]]
                                  $) [[?mage]]]
                  [?name :age ?mage]]
       [["John" :age 20]
        ["Bill" :age 25]
        ["Jack" :age 20]
        ["Steve" :age 28]
        ["Andrew" :age 30]])
    

    返回:

    #{["John" 20] ["Jack" 20]}
    

    【讨论】:

      【解决方案2】:

      这将是一个纯粹的 Datalog 解决方案

      (let [db [["John" 20]
                ["Bill" 25]
                ["Jack" 20]
                ["Steve" 28]
                ["Andrew" 30]]]
        (d/q '[:find ?name ?min-age
               :in $ ?min-age
               :where [?name ?min-age]]
             db
             (ffirst (d/q '[:find (min ?age)
                            :in [[?name ?age]]]
                       db))))
      

      SQL 中的 HAVING 子句不是查询语言的一部分,但由于所有查询都在对等方中执行,因此执行嵌套查询没有开销。

      【讨论】:

      • 我做了同样的解决方案。但我认为 2 个查询不好。用一个纯粹的查询来做这件事是真的吗?
      • 这取决于你认为什么是“坏的”。如果这意味着很多代码,您可以使用@user1641001 的解决方案(先用 take-while 替换)。如果它意味着“不好”,因为这会像使用 SQL 时那样对查询性能不利,但事实并非如此,因为您的查询是在对等点本地运行的。
      【解决方案3】:

      在这种情况下,您不需要 datomic,因为您的序列中已经拥有所有需要的数据。请改用 clojure sort

      (first (sort-by second [...]))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-25
        • 2021-01-02
        • 2013-05-16
        • 2017-06-12
        • 2016-04-26
        • 2013-01-11
        • 1970-01-01
        相关资源
        最近更新 更多