2017-10-20 8 views
0

org.drools.compiler.lang.apiで提供されているRuleDescrBuilder APIを使用して作成したDrLファイルで、次の構造を使用しています。Drools:AfterMatchFiringEventがOR条件付きの同じルールに対して複数回トリガーしていますか?

私は、バックエンドの各ルールのヒット数を追跡​​するために、後のイベントをトリガーします。ただし、入力(述語)がRule1のすべての条件に一致すると、1つの入力に対して複数のafterMatchFiredEventsがトリガーされます。

import com.objects.Predicate 

global com.Util policyUtil 

dialect "java" 

rule "Rule1:RuleId" 
    salience 2147483647 
when 
    predicate := Predicate() 
    (
    eval(policyUtil.evaluate(condition1)) or 
    eval(policyUtil.evaluate(condition2)) or 
    eval(policyUtil.evaluate(condition3)) 
then 

... 

end 

rule "defaultRule:defaultRule" 
    salience 0 
when 
    predicate := Predicate() 
then 

predicate.setValue1("default1"); 
predicate.setValue2("Default2"); 
drools.halt(); 

end 

これは一致イベントトリガの後です:

 public void afterMatchFired(AfterMatchFiredEvent event) { 
      logger.info("Matching rule Name:: " + event.getMatch().getRule().getName()); 
      updateHitCountForRule(event.getMatch().getRule().getName()); 
     } 

これはruledescbuilderが使用されている方法です。

 RuleDescrBuilder rdb = pdb.newRule(); 
     CEDescrBuilder<?, ?> cedb = rdb.lhs(); 
     cedb = cedb.and(); 
     for(each condition in rule) 
      cedb.eval().constraint(constraint).end(); 

Q:afterMatchFireがOR条件付きの同じルールに対して何度もトリガーされるのはなぜですか?私はevalが正しく使用されていないと仮定しています。 evalが正しく使用されない場合、上記の方法を使用してこの種のルールセットを構築する正しい方法は何ですか?

答えて

1

Droolsがパターン間でor演算子を処理する方法が原因です。どのような舞台裏で起こっていることはDroolsのは、あなたの元のルールから3つの異なるルール作成することです:あなたが見ることができるように

rule "Rule1:RuleId 1" 
salience 2147483647 
when 
    predicate := Predicate()  
    eval(policyUtil.evaluate(condition1)) 
then 
    ... 
end 

rule "Rule1:RuleId 2" 
salience 2147483647 
when 
    predicate := Predicate()  
    eval(policyUtil.evaluate(condition2)) 
then 
    ... 
end 

rule "Rule1:RuleId 3" 
salience 2147483647 
when 
    predicate := Predicate()  
    eval(policyUtil.evaluate(condition3)) 
then 
    ... 
end 

を、Droolsの中のパターンの間には短絡or演算子はありません。 evalがすべて一致する場合は、AfterMatchFiredEventが3回だけ受け取られるだけでなく、のルールも3回実行されます。あなたは意志、このシナリオでは

rule "Rule1:RuleId" 
salience 2147483647 
when 
    not RuleExecuted() 
    predicate := Predicate() 
    (
     eval(policyUtil.evaluate(condition1)) or 
     eval(policyUtil.evaluate(condition2)) or 
     eval(policyUtil.evaluate(condition3)) 
    ) 
then 
    ... 
    insert(new RuleExecuted()); 
end 

は(それは少しハックであっても)これを回避する1つの可能な方法は、 action一部の複数の実行を避けるためにフラグとして事実を使用する

ある リスナーで3 BeforeMatchFiredEventのイベントを受信しますが、1つだけの場合はAfterMatchFiredEventとなります。 2 MatchCancelledEventイベントも受信します。

希望します。

+0

ありがとうエステバン。 OR条件をEVAL(policyUtil.evaluate(condition1)|| policyUtil.evaluate(condition2)..)の形で1つのEVAL内で実行しました。これにより、ただ1つのイベントが発生し、期待どおりに動作しました。 – Shashank

関連する問題