2013-09-24 17 views
5

Ich versuche Hände an der Drools-Regel-Engine, ich bin ein ziemlich Anfänger.Drools: Regeln ausgeführt mehr als einmal

Ich habe die folgenden Regeln in einer einzigen Regeldatei:

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 

Im StatefulKnowledgeSession ich zwei Konten bin vorbei, ein mit Balance 15000 andere mit Balance 15,

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(); 

Laut mir sollte das erwartete Ergebnis sein, dass jede Regel nur einmal ausgelöst werden sollte und das entsprechende Objekt gedruckt werden sollte.

Aber das Ergebnis I bin immer:

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

ich nicht in der Lage bin zu verstehen, warum jede Regel zweimal ausgeführt wird ????

Antwort

6

Wenn Sie mehrere Muster verwenden (und keine Beziehung zwischen ihnen angeben), wird ein vollständiges kartesisches Produkt erstellt (genau wie ein select für mehrere Tabellen ohne Join-Klausel). So die Regel:

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

aktiviert N^2 mal für N Objekte vom Typ Konto werden. Eine Lösung könnte das magische Feld ‚dies‘ zu benutzen, um anzugeben, dass das zweite Konto die gleiche wie die erste ist:

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

Aber zurück zu Ihrem Beispiel, ich glaube, Sie brauchen noch nicht einmal um 2 verschiedene Muster zu verwenden. Sie könnten Ihre Regeln wie folgt umschreiben:

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 

Hoffe, dass es hilft,

+0

Bang on! das hat es behoben! – Samrat

2

ich zwei Objekte der gleichen Klasse wurde zu vergleichen und frage mich, warum die Regeln mehrmals gefeuert bekommen. Nach dem Lesen der Erklärung von Esteban Aliverti dachte ich, dass meine Regel auch ein kartesisches Produkt erstellen könnte.

Also ich ersetzt "und" von den Regeln zu "," und es hat perfekt funktioniert. Ich konnte jedoch nicht verstehen, warum "und" kartesisches Produkt kreierte.

Früher meine Regel war -

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 

Später meine Regel wurde (und es funktioniert absolut in Ordnung) -

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

In der ersten Regel wird jedes Muster für jedes RuleC-Objekt in Ihrem Arbeitsspeicher abgeglichen und wenn die Einschränkungen übereinstimmen, wird die Regel ausgelöst. Wie in "wenn es ein RuleC-Objekt gibt (zuerst) und es gibt ein RuleC-Objekt, für das outcome

Verwandte Themen