簡體   English   中英

Drools:AfterMatchFiringEvent為具有OR條件的同一規則多次觸發?

[英]Drools: AfterMatchFiringEvent triggering multiple times for the same rule with OR conditions?

我在使用org.drools.compiler.lang.api隨附的RuleDescrBuilder API構建的DrL文件中使用以下結構。

我觸發一個賽后事件,以跟蹤后端中每個規則的命中數。 但是,當input(Predicate)匹配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();

問:為什么afterMatchFired對於具有OR條件的同一規則會多次觸發? 我假設沒有正確使用eval。 如果未正確使用eval,使用上述方法構建這種規則集的正確方法是什么?

這是因為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匹配,您不僅將收到3次AfterMatchFiredEvent ,而且規則的action部分還將執行3次。

避免發生這種情況的一種可能方法(即使有點怪異)是將事實用作標記,以避免重復執行action部分:

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

在這種情況下,你仍然會收到3個BeforeMatchFiredEvent事件偵聽器,但只有1 AfterMatchFiredEvent 您還將收到2個MatchCancelledEvent事件。

希望能幫助到你,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM