LoginSignup
1
0

More than 5 years have passed since last update.

前回

clara-rulesのaccumulator機能を使うとsqlで言うところの集約関数のような事が実現できるので今回はそれを試してみることにする。

概要

  • clara.rules.accumulatorsのネームスペースにあるものを利用する
  • デフォルトでmin/max/sum等が提供されている
    • 自分で任意のaccumulatorを作成する事もできる(accum関数)
  • defruleの左辺、defqueryで使用することができる

文法

[<束縛する変数名> <- <accumulator> :from [<ファクト>+<constraint>]]

動かしてみる

以下のようなコードを試してみた。


(ns clara-rules.accumulator
  (:require [clara.rules :refer [fire-rules insert mk-session query defquery]]
            [clara.rules.accumulators :as acc]))

(defrecord SomeAmount [id amt])

(defquery test-query
  []
  [?largest-amt <- (acc/max :amt) :from [SomeAmount]]
  [?total <- (acc/sum :amt) :from [SomeAmount]]
  [?grouped <- (acc/grouping-by :id) :from [SomeAmount]]
  ;;Total by groups
  [?grouped-and-summed
   <- (acc/grouping-by :id (fn [m]
                             ;;Accepts map key=field for grouping
                             ;;value=seq of maps of records that were grouped
                             (map (fn [[k seq-of-records]]
                                    {k (reduce + (map :amt seq-of-records))})
                                  m)))
   :from [SomeAmount]])

(-> (mk-session)
    (insert (->SomeAmount :a 4)
            (->SomeAmount :a 8)
            (->SomeAmount :b 32)
            (->SomeAmount :b 21)
            (->SomeAmount :c 1)
            (->SomeAmount :c 9))
    (fire-rules)
    (query test-query))
;; => ({:?largest-amt 32,
;;      :?total 75,
;;      :?grouped {:a [#clara_rules.accumulator.SomeAmount{:id :a, :amt 4}
;;                     #clara_rules.accumulator.SomeAmount{:id :a, :amt 8}],
;;                 :b [#clara_rules.accumulator.SomeAmount{:id :b, :amt 32}
;;                     #clara_rules.accumulator.SomeAmount{:id :b, :amt 21}],
;;                 :c [#clara_rules.accumulator.SomeAmount{:id :c, :amt 1}
;;                     #clara_rules.accumulator.SomeAmount{:id :c, :amt 9}]},
;;      :?grouped-and-summed ({:a 12} {:b 53} {:c 10})})
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0