【问题标题】:How to sum values including entities with missing attributes on Datalog/DataScript/Datomic如何对包括在 Datalog/DataScript/Datomic 上缺少属性的实体在内的值求和
【发布时间】:2021-06-13 20:52:39
【问题描述】:

我正在学习 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)

由于or-join 的第二部分无法为?amount 赋值,因此会引发消息Query for unknown vars: [?amount] 的异常。

【问题讨论】:

    标签: clojure datomic datalog datascript


    【解决方案1】:

    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

    【讨论】:

    • 效果很好,但有点棘手。据我了解,您使用identity 对free-var ?sum-term 进行一些绑定。我也使用(group 0) ?sum-term 对其进行了测试,它给出了相同的结果。使用group 代替identity 有什么问题吗?
    • @Peluko 我猜你的意思是(ground 0) ?sum-term?这似乎工作正常,但我个人觉得它在语义上不太规则,这可能会使代码更难阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多