Как суммировать значения, включая объекты с отсутствующими атрибутами, в Datalog/DataScript/Datomic

Я изучаю Datalog / DataScript / Datomic. Для этого я установил простую базу данных бухгалтерской книги на DataScript, чтобы с ней поиграть. На данный момент он в основном состоит из набора учетных записей и списка записей с атрибутами :entry.record/accountа также . Теперь пытаюсь получить баланс всех счетов, суммируя все :entry.record/ammountдля каждой учетной записи. Этот запрос дает мне баланс для всех счетов , для которых есть записи в бухгалтерской книге:

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

Но у меня есть учетные записи, для которых все еще нет зарегистрированных записей, и они не отображаются здесь. Я хочу сделать запрос, который включает их со значением 0. Я играл с и missing?чтобы включить эти учетные записи в запрос, но я понятия не имею, как получить сумму, равную 0 для учетных записей. Например, такой запрос:

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

Выдает исключение с сообщением Query for unknown vars: [?ammount] поскольку вторая часть or-join не могу присвоить значение ?ammount.

1 ответ

Решение

Datomic Datomic определенно неудобен для такого рода агрегации; я действительно рекомендую использовать or-join, чтобы получить нулевую сумму:

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

См. Также: Datomic aggregations: подсчет связанных сущностей без потери результатов с нулевым счетом

Другие вопросы по тегам