2013-09-24 115 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對象(第一個)並且存在結果