2013-09-24 5 views
5

私はDroolsルールエンジンを試しています。私はかなり初心者です。drools:複数のルールが実行される

I単一のルール・ファイル内の代わりに、以下の規則があります。私は2つのアカウント、バランス15とのバランス15000別のものを渡していますStatefulKnowledgeSessionで

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 

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

を私によると、予想される結果は、各ルールが1回だけ起動され、対応するオブジェクトが印刷されるべきであるということです。

しかし、私は取得しています結果は次のとおりです。私は、各ルールが二回実行されている理由を理解することはできませんよ

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

????

答えて

6

複数のパターンを使用すると、それらの間にリレーションを指定しないと、完全なデカルト積が作成されます(結合句のない複数のテーブルの選択と同様)。 ので、ルール:タイプアカウントのN・オブジェクトの

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

が起動されるN^2回。 一つの解決策は、2番目のアカウントが最初のものと同じであることを指定するには、「この」魔法のフィールドを使用することができます

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 

は、私は同じクラスの2つのオブジェクトを比較したルールが複数回解雇されている理由を不思議に思った

+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オブジェクトがある場合(最初)、結果が

関連する問題