多次检查以重新评估 Drools Execution KIE 中的规则结束

Multiple checks end in re-evaluation of rules in Drools Execution KIE

我有一组规则,这些规则根据评估对象的数量表现不同

我希望为每个传递的产品 class 对象执行 2 条规则。

  1. 当我传递 Product 2 规则的单个对象时(这很好)

    Product product5= new Product();
        product5.setType("gold");
        product5.setBuyer("platinum");
        product5.setEvent("sale");
        product5.setName("product5");              
        ksession.insert(product5);
    
  2. 当我传递 Product class 的两个对象时,执行的规则数为 6(我无法理解)。

    Product product5= new Product();
    Product product3= new Product();
    //setting all fields in both objects
    ksession.insert(product5);
    ksession.insert(product3);
    

    我尝试通过添加控制台打印来调试它,这是我的结果

    为每个对象执行一次黄金报价(预期)。

    为每个对象(应该是两个)执行两次节日黄金报价。

    未调用钻石报价(预期)

  3. 当我传递 Product class 的三个对象时,执行的规则数为 12(我无法理解)。 我尝试通过添加控制台打印来调试它,这是我的结果

    为每个对象执行一次黄金报价(预期)。

    节日黄金报价为每个对象执行三次(应该是两次)。

    未调用钻石报价(预期)

下面是我的DRL文件

    rule "Offer for Diamond"
    when
    $productObject: Product(type == "diamond")
    then
    $productObject.setDiscount(15);
    end


    rule "Offer for Gold"
    salience 1

    when
    $productObject: Product(type == "gold")
    then
    $productObject.setDiscount(25);
    end


    rule "Offer for Gold on Festival"
    when
    $productObject: Product(type == "gold") && Product(event == "sale")
    then
    $productObject.setDiscount($productObject.getDiscount() + 5);
    end

假设您的 2 个对象具有相同的属性,这些是执行的规则(和事实):

  • "Offer for Diamond": 0 次
  • "Offer for Gold": 2 次:
    • o1
    • o2
  • "Offer for Gold on Festival":4次
    • o1, o1
    • o1,o2
    • o2,o1
    • o2,o2

如您所见,当您在模式之间使用 && 时,您正在创建匹配它们的所有可能组合的笛卡尔积。

在"Offer for Gold on Festival"中,如果您希望规则对每个对象执行一次,那么您必须明确告诉 Drools 这 2 个模式在谈论同一个对象:

rule "Offer for Gold on Festival"
when
    $productObject: Product(type == "gold") && 
    Product(this == $productObject, event == "sale")
then
    $productObject.setDiscount($productObject.getDiscount() + 5);
end

现在,如果您的规则与上面的完全一样,只需执行以下操作即可简化:

rule "Offer for Gold on Festival"
when
    $productObject: Product(type == "gold", event == "sale")
then
    $productObject.setDiscount($productObject.getDiscount() + 5);
end

在这种情况下,因为您没有 2 个模式,所以规则将只对每个 Product.

评估一次

希望对您有所帮助,