Drools Window 长度和行为

Drools Window length and from behaviour

我正在使用以下规则在发送 1 个绿色数据包后发送红色数据包的情况下触发警报

package com.myspace.floodmonitoringrules;

import java.lang.Number;
import java.util.ArrayList;

rule "rule3"
    dialect "mvel"
    enabled true
    when
        w : ArrayList( size() == 1 ) from collect ( devicestatus( flood_status_color == "green" ) over window:length (1)) 
        ds : devicestatus( flood_status_color == "red" )
    then
        ds.setFlood_alert( "WindowDetected" );
end

然而,如果之前没有发送绿色数据包,则在发送任何红色数据包后会触发规则。 这是我将 ksession 定义为有状态的。 当我将其定义为无状态时,规则根本不会被触发!

我需要了解流口水的新行为。

这应该符合您的要求

declare Status @role (event) end

rule "rule3"
    dialect "mvel"
    enabled true
    when
        $list : List() from collect (Status() over window:length (2))
        $g : Status( floodStatusColor == "green" ) from $list
        $r : Status( floodStatusColor == "red", this after $g ) from $list 
    then
        System.out.println("WindowDetected")
end

测试

@DroolsSession("test.drl")
public class PlaygroundTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    public void testIt() {
        drools.insertAndFire(new Status("red"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("green"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("green"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("red"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("green"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("red"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("red"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("red"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("green"));
        drools.advanceTime(1, SECONDS);
        drools.insertAndFire(new Status("red"));
    }

产出

00:00:00 --> inserted: Status[floodStatusColor=red]
00:00:00 --> fireAllRules
00:00:01 --> inserted: Status[floodStatusColor=green]
00:00:01 --> fireAllRules
00:00:02 --> inserted: Status[floodStatusColor=green]
00:00:02 --> fireAllRules
00:00:03 --> inserted: Status[floodStatusColor=red]
00:00:03 --> fireAllRules
00:00:03 <-- 'rule3' has been activated by the tuple [InitialFactImpl, ArrayList, Status, Status]
WindowDetected
00:00:04 --> inserted: Status[floodStatusColor=green]
00:00:04 --> fireAllRules
00:00:05 --> inserted: Status[floodStatusColor=red]
00:00:05 --> fireAllRules
00:00:05 <-- 'rule3' has been activated by the tuple [InitialFactImpl, ArrayList, Status, Status]
WindowDetected
00:00:06 --> inserted: Status[floodStatusColor=red]
00:00:06 --> fireAllRules
00:00:07 --> inserted: Status[floodStatusColor=red]
00:00:07 --> fireAllRules
00:00:08 --> inserted: Status[floodStatusColor=green]
00:00:08 --> fireAllRules
00:00:09 --> inserted: Status[floodStatusColor=red]
00:00:09 --> fireAllRules
00:00:09 <-- 'rule3' has been activated by the tuple [InitialFactImpl, ArrayList, Status, Status]
WindowDetected

你可能想看看similar question,更复杂更有趣


不滑动的替代解决方案windows如果您不需要其他规则的旧事件

rule "rule3"
    when
        $g : Status( floodStatusColor == "green" )
        $r : Status( floodStatusColor == "red", this after $g ) 
    then
        System.out.println("WindowDetected");
end

rule "rule3 cleanup"
    salience -1
    when
        $e : Status()
        Status( this after $e ) 
    then
        delete($e);
end

我添加了缩回( $g );到您的代码,那么它现在可以正常工作了。

rule "rule3"
    dialect "mvel"
    enabled true
    when
        $list : List() from collect (Status() over window:length (2))
        $g : Status( floodStatusColor == "green" ) from $list
        $r : Status( floodStatusColor == "red", this after $g ) from $list 
    then
        System.out.println("WindowDetected")
        retract( $g );

end