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

How to sum values including entities with missing attributes on 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