如何对包括 Datalog/DataScript/Datomic 上缺少属性的实体的值求和

问题描述

我正在学习 Datalog/DataScript/Datomic。为此,我在 DataScript 上设置了一个简单的分类数据库来使用。到目前为止,它基本上由一组帐户和具有属性 :entry.record/account:entry.record/amount 的记录列表组成。现在我试图通过对每个帐户的所有 :entry.record/amount 求和来获得所有帐户的余额。此查询为我提供了分类帐上有记录的所有帐户的余额:

  (d/q '[:find ?account ?account-name (sum ?amount)
     :with ?record
     :in $
     :where [?account :account/name ?account-name]
            [?record :entry.record/account ?account]
            [?record :entry.record/amount ?amount]]
   @conn)

但是我有一些帐户还没有注册任何记录,而且它们没有出现在这里。我想进行一个包含它们的查询,以 0 值列出。我一直在使用 or-joinmissing? 将这些帐户包含在查询中,但我不知道如何将帐户的金额设为 0。例如,这个查询

  (d/q '[:find ?account ?account-name (sum ?amount)
     :with ?record
     :in $
     :where [?account :account/name ?account-name]
     (or-join [?record]
              (and [?record :entry.record/account ?account]
                   [?record :entry.record/amount ?amount])
              [(missing? $ ?record :entry.record/account)])]
   @conn)

抛出消息 Query for unkNown vars: [?amount] 的异常,因为 or-join 的第二部分无法为 ?amount 赋值。

解决方法

Datomic 的 Datalog 绝对不适合这种聚合;我的建议确实是使用 or-join 以发出零数量:

[:find ?account ?account-name (sum ?amount)
 :with ?sum-term
 :in $
 :where [?account :account/name ?account-name]
 (or-join [?account ?amount ?sum-term]
   (and
     [?sum-term :entry.record/account ?account]
     [?sum-term :entry.record/amount ?amount])
   (and
     [(identity ?account) ?sum-term]
     [(ground 0) ?amount]))]

另见:Datomic aggregations: counting related entities without losing results with zero-count

相关问答

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