Drools:AfterMatchFiringEvent触发与OR条件相同的规则多次?
问题描述:
我在使用org.drools.compiler.lang.api提供的RuleDescrBuilder API构建的DrL文件中使用以下结构。Drools:AfterMatchFiringEvent触发与OR条件相同的规则多次?
我触发了匹配后事件,以跟踪后端中每个规则的匹配数量。但是,当输入(Predicate)匹配Rule1中的所有给定条件时,它将为一个输入触发多个afterMatchFiredEvents。
import com.objects.Predicate
global com.Util policyUtil
dialect "java"
rule "Rule1:RuleId"
salience 2147483647
when
predicate := Predicate()
(
eval(policyUtil.evaluate(condition1)) or
eval(policyUtil.evaluate(condition2)) or
eval(policyUtil.evaluate(condition3))
then
...
end
rule "defaultRule:defaultRule"
salience 0
when
predicate := Predicate()
then
predicate.setValue1("default1");
predicate.setValue2("Default2");
drools.halt();
end
这是比赛后的事件触发:
public void afterMatchFired(AfterMatchFiredEvent event) {
logger.info("Matching rule Name:: " + event.getMatch().getRule().getName());
updateHitCountForRule(event.getMatch().getRule().getName());
}
这是ruledescbuilder是如何使用的。
RuleDescrBuilder rdb = pdb.newRule();
CEDescrBuilder<?, ?> cedb = rdb.lhs();
cedb = cedb.and();
for(each condition in rule)
cedb.eval().constraint(constraint).end();
问:为什么afterMatchFired多次触发与OR条件相同的规则?我假设eval未被正确使用。如果eval没有被正确使用,那么使用上述方法构建这种规则集的正确方法是什么?
答
这是因为Drools在模式之间处理or
运算符的方式。这是怎么回事幕后是Drools的创建从原来的第3个不同的规则:
rule "Rule1:RuleId 1"
salience 2147483647
when
predicate := Predicate()
eval(policyUtil.evaluate(condition1))
then
...
end
rule "Rule1:RuleId 2"
salience 2147483647
when
predicate := Predicate()
eval(policyUtil.evaluate(condition2))
then
...
end
rule "Rule1:RuleId 3"
salience 2147483647
when
predicate := Predicate()
eval(policyUtil.evaluate(condition3))
then
...
end
正如你所看到的,有在Drools中的图案之间无短路or
运营商。如果你所有的eval
匹配,你不但会收到3次AfterMatchFiredEvent
,你的规则的action
部分也会被执行3次。
一个可能的方法来避免这种情况(即使它是一个有点哈克)是用事实作为标志,以免action
部分执行多次:
rule "Rule1:RuleId"
salience 2147483647
when
not RuleExecuted()
predicate := Predicate()
(
eval(policyUtil.evaluate(condition1)) or
eval(policyUtil.evaluate(condition2)) or
eval(policyUtil.evaluate(condition3))
)
then
...
insert(new RuleExecuted());
end
在这种情况下,你会在听众中仍然收到3个BeforeMatchFiredEvent
事件,但只有1 AfterMatchFiredEvent
。您也将收到2个MatchCancelledEvent
事件。
希望它有帮助,
谢谢埃斯特万。我以eval(policyUtil.evaluate(condition1)|| policyUtil.evaluate(condition2)..)的形式在单个EVAL中执行OR条件。这只触发了一个事件并按预期工作。 – Shashank