如何控制 Drools 中的规则评估(或规则执行)阶段?
How to control rule evaluation (or rule execution) stages in Drools?
我知道 Drools 中的 "salience" 提供了规则执行顺序下的控制。但上面是我遇到的 "saliences" 无能为力的问题示例。
这里我依次执行了三个规则:
rule "Rule 1"
salience 30
when
then
Resource resource1 = new Resource();
resource1.setName("Resource 1");
resource1.setAmount("5");
insert(resource1);
System.out.println("First");
end
rule "Rule 2"
salience 20
//no-loop (interesting, it doesn't lead to a loop)
when
$resource1: Resource(name == "Resource 1")
then
modify($resource1) {setAmount("20")};
System.out.println("Second");
end
rule "Rule 3"
salience 10
when
$resource1: Resource(name == "Resource 1",
Double.parseDouble(amount) > 10)
then
System.out.println("Rule is fired");
end
我预计第三条规则会被触发并且控制台中有 "Rule is fired" 行,但它没有被执行。
据我了解,问题出在规则评估阶段,当所有三个规则在执行前立即评估,然后才根据它们的 "salience" 轮次执行。
在评估时 $resource1.amount 是 5,这就是第三条规则未被触发的原因。如果您在第一条规则中放置的数字大于 10,则将触发 3d 规则。如果你根本不设置金额 - 它会导致异常。
我该如何解决这个问题才能触发 3d 规则?
在文档中查找 Agenda/activation 组,您可以使用该概念控制规则组的执行
我的猜测是 Drools 不理解当您更改事实的 amount
时必须重新评估表达式 Double.parseDouble(amount) > 10
。问题与您编写表达式的方式有关。
你可以看看我在的回答。看一下 "Another solution" 部分。
我建议您做的是修改您的模型并向您添加一个 getAmountAsDouble()
方法 class 以便在其中进行转换。您还需要注释 setAmount()
方法,让 Drools 知道它修改了 getAmountAsDouble()
:
返回的值
public class Resource {
private String amount;
@Modifies( { "amountAsDouble" } )
private void setAmount(String amount){
this.amount = amount;
}
private String getAmount(){
return this.amount;
}
private String getAmountAsDouble(){
return Double.parseDouble(this.amount);
}
}
现在您的规则可以重写为:
rule "Rule 3"
salience 10
when
$resource1: Resource(name == "Resource 1",
amountAsDouble > 10)
then
System.out.println("Rule is fired");
end
希望对您有所帮助,
所以这是一个错误,现在已在最近一次更新中修复。
这是问题所在:https://issues.jboss.org/browse/DROOLS-3972
我测试了代码,触发了规则 3
drools.version 7.32.0.Final
我知道 Drools 中的 "salience" 提供了规则执行顺序下的控制。但上面是我遇到的 "saliences" 无能为力的问题示例。
这里我依次执行了三个规则:
rule "Rule 1"
salience 30
when
then
Resource resource1 = new Resource();
resource1.setName("Resource 1");
resource1.setAmount("5");
insert(resource1);
System.out.println("First");
end
rule "Rule 2"
salience 20
//no-loop (interesting, it doesn't lead to a loop)
when
$resource1: Resource(name == "Resource 1")
then
modify($resource1) {setAmount("20")};
System.out.println("Second");
end
rule "Rule 3"
salience 10
when
$resource1: Resource(name == "Resource 1",
Double.parseDouble(amount) > 10)
then
System.out.println("Rule is fired");
end
我预计第三条规则会被触发并且控制台中有 "Rule is fired" 行,但它没有被执行。
据我了解,问题出在规则评估阶段,当所有三个规则在执行前立即评估,然后才根据它们的 "salience" 轮次执行。
在评估时 $resource1.amount 是 5,这就是第三条规则未被触发的原因。如果您在第一条规则中放置的数字大于 10,则将触发 3d 规则。如果你根本不设置金额 - 它会导致异常。
我该如何解决这个问题才能触发 3d 规则?
在文档中查找 Agenda/activation 组,您可以使用该概念控制规则组的执行
我的猜测是 Drools 不理解当您更改事实的 amount
时必须重新评估表达式 Double.parseDouble(amount) > 10
。问题与您编写表达式的方式有关。
你可以看看我在
我建议您做的是修改您的模型并向您添加一个 getAmountAsDouble()
方法 class 以便在其中进行转换。您还需要注释 setAmount()
方法,让 Drools 知道它修改了 getAmountAsDouble()
:
public class Resource {
private String amount;
@Modifies( { "amountAsDouble" } )
private void setAmount(String amount){
this.amount = amount;
}
private String getAmount(){
return this.amount;
}
private String getAmountAsDouble(){
return Double.parseDouble(this.amount);
}
}
现在您的规则可以重写为:
rule "Rule 3"
salience 10
when
$resource1: Resource(name == "Resource 1",
amountAsDouble > 10)
then
System.out.println("Rule is fired");
end
希望对您有所帮助,
所以这是一个错误,现在已在最近一次更新中修复。 这是问题所在:https://issues.jboss.org/browse/DROOLS-3972
我测试了代码,触发了规则 3
drools.version 7.32.0.Final