2017-10-20 16 views
0

org.drools.compiler.lang.api와 함께 제공되는 RuleDescrBuilder API를 사용하여 작성된 DrL 파일에서 다음 구조를 사용하고 있습니다.Drools : AfterMatchFiringEvent가 OR 조건이있는 동일한 규칙에 대해 여러 번 트리거됩니까?

나는 경기 후 이벤트를 트리거하여 백엔드의 각 규칙에 대한 히트 수를 추적합니다. 그러나 입력 (조건부)이 Rule1의 모든 조건과 일치하면 하나의 입력에 대해 여러 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 : OR 조건이있는 동일한 규칙에 대해 afterMatchFired가 여러 번 트리거되는 이유는 무엇입니까? 나는 그 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 

:

은 (조금 해키 경우에도)이을 피하기 위해 한 가지 방법은 action 부분의 여러 실행을 방지하기 위해 플래그로 사실을 사용하는

입니다 청취자에게는 여전히 3 BeforeMatchFiredEvent 이벤트가 수신되지만 1 AfterMatchFiredEvent 만 수신합니다. 2 MatchCancelledEvent 이벤트도 수신하게됩니다.

희망 하시겠습니까?

+0

감사합니다. Esteban. 나는 EVAL (policyUtil.evaluate (condition1) || policyUtil.evaluate (condition2) ..)의 형태로 단일 EVAL 내에서 OR 조건을 실행했습니다. 이로 인해 단 한 번의 이벤트가 발생하고 예상대로 작동했습니다. – Shashank