2013-09-24 79 views
5

我正在尝试在Drools规则引擎上工作,我是一个初学者。drools:规则执行超过一次

我已经制定了以下规则在一个规则文件:

rule "A stand alone rule" 
salience 2 
no-loop 
when 
    $account : Account() 
    Account($account.balance>100) 
then 
    System.out.println("balance>100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName());  
end 

rule "A second Rule" 
salience 1 
no-loop 
when 
    $account : Account() 
    Account($account.balance<100) 
then 
    System.out.println("balance<100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName()); 
end 

在我传递两个帐户,一个具有平衡15000另一个与平衡15 StatefulKnowledgeSession,

Account account=new Account(7l,15000l); 
     Account account1=new Account(5l,15l); 

     Customer customer = new Customer("Samrat", 28, "Sector51", account); 
     Customer customer1 = new Customer("Alexi", 28, "Sector50", account1); 
     account.setCustomer(customer); 
     account1.setCustomer(customer1); 
     session.insert(account); 
     session.insert(account1); 

     session.fireAllRules(); 

根据我的预期结果应该是,每个规则只能被触发一次,并且相应的对象应该被打印。

但我得到的结果是:

balance>100 
15000 
Samrat 
balance>100 
15000 
Samrat 
balance<100 
15 
Alexi 
balance<100 
15 
Alexi 

我无法理解为什么每个规则运行两次????

回答

6

使用多个模式(并且不指定它们之间的任何关系)将创建一个完整的笛卡尔积(就像多个表上没有连接子句的选择一样)。 所以,规则:

rule A 
when 
    Account() 
    Account() 
then 
    ... 
end 

将被激活N^2次类型的帐户N个对象。 一种解决方案可能是使用魔术场“这个”指定的第二个帐户是一样的第一个:

rule A 
when 
    $a: Account() 
    Account(this == $a) 
then 
    ... 
end 

但是,回到你的榜样,我想你甚至不需要使用2种不同的模式。你可以重写你的规则如下:

rule "A stand alone rule" 
salience 2 
no-loop 
when 
    $account: Account(balance>100) 
then 
    System.out.println("balance>100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName());  
end 

rule "A second Rule" 
salience 1 
no-loop 
when 
    $account: Account(balance<100) 
then 
    System.out.println("balance<100"); 
    System.out.println($account.getBalance()); 
    System.out.println($account.getCustomer().getName()); 
end 

希望它能帮助,

+0

中邦!这固定它! – Samrat

2

我比较同一类的两个对象,想知道为什么规则被炒鱿鱼多次。然而,在阅读Esteban Aliverti的解释后,我认为我的规则也可能是创造笛卡尔产品。

因此,我将“和”从规则替换为“,”并且它的工作完美。但是,我不明白为什么“和”创造笛卡尔产品。

早些时候我的规则是 -

rule "Rule 1" 
    when 
     $first : RuleC() and 
     second : RuleC(this != $first) and 
      RuleC($first.outcome < outcome) and 
      RuleC($first.target == target) 
    then 
     System.out.println("The rule has been fired "); 
end 

后来我成了规则(它是工作绝对没问题) -

rule "Rule 1" 
    when 
     $first : RuleC() and 
     second : RuleC(this != $first, $first.outcome < outcome, $first.target == target) 
    then 
     System.out.println("The rule has been fired "); 
end 
+0

在第一条规则中,每个模式将与工作内存中的每个RuleC对象相匹配,并且如果约束符合规则将触发。如“如果存在RuleC对象(第一个)并且存在结果