I’m trying to figure out if there is a way to accumulate some joined data. I haven’t been able to come up with a single rule which will fire with my desired output.
In the following example, I am trying to answer the question, what is the sum of quantities
for each name
:
(defrecord A [id name])
(defrecord B [id quantity])
(defrule merge-things
???
=>
(println ?name ?total-quanity))
(-> (mk-session)
(insert (->A 1 "car"))
(insert (->A 2 "truck"))
(insert (->A 3 "car"))
(insert (->B 1 2))
(insert (->B 2 3))
(insert (->B 3 5))
(fire-rules))
I am trying to have that rule print out:
car 7
truck 3
I haven’t been able to come up with a ???
for that rule which works.
Well, :duckie: to the rescue. While typing this up, I found one way I hadn’t tried. So now my question is, are there any problems with the following rule definition? (memory,performance,other,…)
It is different that other rules I’ve used. Not sure if using the accumulator and re-creating the set of ids — (set (map :id ?a))
— in the rule expression would cause any unexpected problems.
(defrule merge-things
[?a <- (acc/all) :from [A (= ?name name)]]
[?total-quantity <- (acc/sum :quantity) :from [B (get (set (map :id ?a)) id)]]
=>
(println ?name ?total-quantity))