1
votes

I am inserting data to drools rule engine but i can not understand how it processed inserted data. The code for inserting data is:

final StatefulKnowledgeSession session = getSession()
        new Thread() {
                    @Override public void run() {
                        Thread.currentThread().setName("RuleEngineThread")
                        println 'engine starting fire'+Thread.currentThread().getName()
                        session.fireUntilHalt();
                    }
                }.start();
        WorkingMemoryEntryPoint entrypoint=session.getWorkingMemoryEntryPoint("Multiple Stream")
        entrypoint.insert(new Categories([categoryid:120,name:"catN1"]))
        entrypoint.insert(new Test(100,120))

        entrypoint.insert(new Categories([categoryid:121,name:"catN2"]))
        entrypoint.insert(new Test(100,121))
        entrypoint.insert(new Categories([categoryid:1220,name:"catN3"]))
        entrypoint.insert(new Test(100,1220))
        entrypoint.insert(new Categories([categoryid:1202,name:"catN4"]))
        entrypoint.insert(new Test(100,1202))
        println "Thread sleeeping for 3 secs"
        Thread.currentThread().sleep(3000)

don't worry for syntax this is groovy file. And the rule being:

 rule "multiple-opt"
   //duration  120
    no-loop true
 when
 $c: Categories() from entry-point "Multiple Stream"
 $t: Test()  from entry-point "Multiple Stream"
 then
 System.out.println("@@Multiple "+$c.getName()+":"+$t.getPrice());
 end

The output i am getting is quite strange so I think i have less understanding of drools runtime. The output is :

engine starting fireRuleEngineThread
Thread sleeeping for 3 secs
@@Multiple catN1:100
@@Multiple catN4:100
@@Multiple catN3:100
@@Multiple catN2:100
@@Multiple catN1:100
@@Multiple catN4:100
@@Multiple catN3:100
@@Multiple catN2:100
@@Multiple catN1:100
@@Multiple catN3:100
@@Multiple catN2:100
@@Multiple catN1:100
@@Multiple catN2:100

I can not understand how rule got fired so many times while i inserted objects less times than the number of outputs i receive.
Please help if i am missing some knowledge about drools.Thanks in advance

2

2 Answers

4
votes

This is a very basic feature of production rule systems: the exhaustive search of all possible combinations as defined by the patterns of a rule.

Categories()    // <= match with any object of class Categories
Test()          // <= match with any object of class Test

You have inserted 4 of each, so the rule will fire for each possible pairing.

1
votes

Just to add to @laune, depending on your scenario, you can e.g. retract each pair of facts after a match:

then
 System.out.println("@@Multiple "+$c.getName()+":"+$t.getPrice());
 retract($c);
 retract($t);

Edit

Yes, in order to correlate the pairs, you can use a binding variable and then filter on this in the pattern match:

when
 $c: Categories($catid : categoryid ) from entry-point "Multiple Stream"
 $t: Test(categoryid == $catid)  from entry-point "Multiple Stream"
then
 System.out.println("@@Multiple "+$c.getName()+":"+$t.getPrice());

(Assuming that there is a getCategoryId() getter on class Test. Also, correlating in this way will reduce the number of rule match permutations). You might not need to retract the facts if they are matched in correlated pairs this way.