3

嗨,我想在另一组 drools 规则触发时禁用其他一些 drools 规则,你会怎么做?

假设我有一个议程组“每日”,它有两组流口水规则集 A 有规则“Default-1”、“Default-2”、“Default-3” 集 B 有规则“Custom-1”、“自定义 2”、“自定义 3”

当议程组“每日”得到关注,并且当前事实与自定义模式匹配时,我希望仅触发“Custom-1”和/或“Custom-2”和/或“Custom-3”;否则,只有“Default-1”和/或“Default-2”和/或“Default-3”触发。

问题是,Default-1/2/3 总是被解雇。我需要一种在 Custom-1/2/3 中禁用它们的方法。首先,我将 Custom-1/2/3 中的显着性级别设置为高于 Default-1/2/3。然后我尝试使用激活组。但是,如果我将它们全部设置为同一个激活组,则六条规则中只有一条会触发,这不是我想要的。

我不允许更改 .java 模块,该模块每次都会加载所有规则。我只能更改 .drl drools 规则。

谢谢你。

4

2 回答 2

6

您可以尝试使用标记对象解决您的问题。假设你定义了一个 Marker 类:

public class Marker {
    String uniqueIdentifier;
    //getter and setter, etc
}

(drools 允许您在 *.drl 代码中定义新类,而无需求助于 *.java)
然后使自定义组在默认组之前运行(显着性可以工作,定义流程也可以工作)并“标记”那些对象通过将新的标记事实插入内存来触发自定义规则,如下所示:

when
   SomeObject($unique: someIdentifier)
   //normal conditions
then
   insert(new Marker($unique))
   //normal action

并且默认规则中的 仅作用于没有触发自定义规则的对象:

when
   SomeObject($unique: someIdentifier)
   not Marker(uniqueIdentifier = $unique)
   //normal conditions
then
   //normal action

此外,为了防止泄漏,您可能需要第三组(最后)规则来清理:

when
   SomeObject($unique: someIdentifier)
   $marker : Marker(uniqueIdentifier = $unique)
then
   retract($marker)
于 2013-01-11T06:40:22.217 回答
1

Drools 使用Declarative Agenda支持这种行为。

它基本上提供了这种上下文方法:

void blockMatch(Match match);
void unblockAllMatches(Match match);
void cancelMatch(Match match);

在规则中阻止其他规则,同时阻止其他规则仍然存在true或它们实际上已明确解除阻止。

于 2016-02-02T00:30:57.393 回答