Drools 流口水:规则触发多次

Drools 流口水:规则触发多次,drools,rule-engine,Drools,Rule Engine,我刚开始流口水,遇到了一个问题 我简化了规则以显示问题: rule "test" when $ev : TestEvent() $evList : ArrayList( size >= 3 ) from collect ( TestEvent(linkId == $ev.getLinkId()) ) then

我刚开始流口水,遇到了一个问题

我简化了规则以显示问题:

    rule "test"

    when
        $ev     : TestEvent()

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

    end
基本上,我想计算发生在特定路段上的事件(路段是道路的一部分)。当同一链接上发生3个事件时,我希望触发规则

上面的规则几乎起作用了,但当它触发时,会触发3次,每个事件触发一次。我只想让它开火一次

我错过了什么


非常感谢。

第一个模式选择任何TestEvent,而不管其linkId如何。如果存在n个具有特定linkId的TestEvent事实,则验证将进行n次

若要将此规则限制为一次触发,您可以从任何此类n组中选择一个TestEvent。可以使用具有唯一有序值的任何属性,如果您有事件,则事件时间戳也可用

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

我改变了解决这个问题的方法,使它起到了作用。我现在创建了链接对象,然后将事件绑定回链接

这条规则结束了

rule "test"

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

end

每个链接只触发一次,这正是我所需要的。

感谢您的回复-这是一种有用的方法。实际上,我重新思考了我正在做的事情,并改变了我构建设计的方式。我已经在下面发布了我使用的解决方案,但将此标记为答案,因为它可能对其他人有用。这是一个更详细的备选方案。另一个使用规则为具有特定linkId的每组TestEvent事实创建、更新和(可选)删除“收集”事实。这样,您就不必麻烦TestEvent本身,您不需要collect,其他的可能性也可以很容易地实现。