当前位置: 首页 > 知识库问答 >
问题:

如何控制Drools中的规则评估(或规则执行)阶段?

孔寒
2023-03-14

我知道Drools中的“显着性”提供了对规则执行顺序的控制。但上面是一个例子,说明了当“显着性”不再能帮助我时所面临的问题。

在这里,我有三条规则正在相继执行:

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

我期望第三条规则被触发,并且控制台中有“规则被触发”行,但它没有被执行。
据我所知,问题在于规则评估阶段,当所有三个规则在执行前同时评估,然后才根据它们的“显着性”回合执行
在评估的那一刻,$resource1.amount是5,这就是为什么第三条规则没有被触发。如果您在第一条规则中输入的数字超过10,则3d规则将触发。如果您根本不设置金额——它会导致异常。
我如何解决这个问题,以便3d规则触发?

共有3个答案

司信厚
2023-03-14

所以这是一个bug,现在在最近的一次更新中修复了它。问题是:https://issues.jboss.org/browse/DROOLS-3972

裴良弼
2023-03-14

查看议程/激活组的文档,您可以使用该概念控制规则组的执行

巫马望
2023-03-14

我猜Drools不明白表达Double.parseDouble(金额)

你可以看看我在另一个问题中的回答。看看“另一种解决方案”部分。

我建议您做的是修改您的模型并将getAmountAsDouble()方法添加到您的类中,以便在其中进行转换。您还需要注释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

希望有帮助,

 类似资料:
  • 我在同一个drl文件中有两个Drools规则,如下所示: 我的想法是用第一条规则处理所有处于临界状态的事件。然后使用第二个规则,如果任何阀门有警报,这是由“如果临界”规则设置的,发送一个短信。 你知道吗?用口水可能吗?

  • 我有这样的情况,在规则文件中的所有规则必须检查执行。如果我的理解是正确的,文档所说的规则将由引擎任意执行。 我有一个或多个疑问。 > 我在许多地方得到了答案,我必须使用显著性功能来按顺序执行它们。如果我使用显著性,并且我有执行所有规则的要求,它真的会大规模地影响性能吗?如果是,它会如何影响性能,甚至规则引擎也会任意执行所有规则,比如一些随机顺序。 提前谢谢。

  • 在我的项目中,我有一些要求,我想使用Drools来适应。有些规则不会经常改变,它们是基础。然后应该有第二个DSLR,它会更频繁地更改,并且应该在其中扩展、覆盖和/或聚合已经定义的规则。 是否可以使用口水来满足此类要求。我更新了Drools文档,但我不确定这是否可行。

  • 我想在不同的规则流中使用一些drools规则。由于Drools规则一次只支持一个规则流组名称,并且规则流业务规则任务也可以映射到单个规则流组,所以我无法在不同的规则流中使用相同的规则。有没有其他方法可以用来过滤规则?比如使用标记或元数据?

  • 我想达到的,大致可以概括为一个简单的或者有条件的。 虽然使用Fluent验证支持其他属性上的条件属性验证(When/Unless ),但似乎没有一种方法支持同一属性上的条件规则。还是我错过了什么? 本质上我想实现: 唯一的替代方法是将规则组合在一个自定义规则中? 然而,这紧密地耦合了规则逻辑,实际上它们是完全独立的条件,我可能想在其他对象/字段上使用。 有人建议在 FluentValidation