Francis Smith
Francis Smith

Reputation: 43

Drools : Rule firing multiple times

I'm new to Drools and have hit a problem.

I've simplified the rule to exhibit the problem:

    rule "test"

    when
        $ev     : TestEvent()

        $evList : ArrayList( size >= 3 ) from collect
                  (
                     TestEvent(linkId == $ev.getLinkId())
                  ) 
    then
       System.out.println("Rule fired!")

    end

Basically, I want to count Events occurring on a particular Link (a Link is a section of road). When 3 events occur on the same Link I want the rule to fire.

The rule above is almost working, but when it fires, it fires 3 times, once for each event. I only want it to fire once.

What am I missing?

Many thanks in advance.

Upvotes: 1

Views: 2564

Answers (2)

Francis Smith
Francis Smith

Reputation: 43

I got this working by changing my approach to the problem. I've created Link objects now and then tie the events back to the Link.

The rule ends up

rule "test"

    when
        $link   : Link()
        $events : ArrayList( size >= 3 ) from collect (TestEvent(link == $link)) 
    then 
        System.out.println("Rule fired!")

end

This only fires once per link which is what I need.

Upvotes: 1

laune
laune

Reputation: 31290

The first pattern picks any TestEvent irrespective of its linkId. If there are n TestEvent facts with a certain linkId, the acivation proceeds n times.

To restrict this rule to fire once you could select a single TestEvent out of any such group of n. Any attribute with a unique ordered value may be used, and if you have events also the event timestamp is available.

rule "test"
when
    $ev: TestEvent( $lid: linkId )
    not TestEvent( linkId == $lid, this before $ev )
    $evList : ArrayList( size >= 3 ) from collect
              (
                 TestEvent(linkId == $lid)
              ) 
then
   System.out.println("Rule fired!")
end

Upvotes: 1

Related Questions