Drools JBOSS rule Nested IF's
The concept of "else" doesn't really translate directly to a declarative language. Instead, you have to explicitly define what "else" truly means in terms of your data and write a rule (or rules) based on that condition. As an example, consider the following conditions:
If Order Total >= 1000
Discount = 15%
Else If Order Total >= 500
Discount = 10%
Else If Order Total >= 250
Discount = 5%
Else
Discount = 0%
The natural first attempt at rules for these conditions might be:
rule "15% discount"
when
$o : Order( total >= 1000 )
then
modify($o) { setDiscount(.15); }
end
rule "10% discount"
when
$o : Order( total >= 500 )
then
modify($o) { setDiscount(.10); }
end
etc...
The problem with this approach is that both the 10% and 15% rules will match for an Order whose total is 1200. This is because the "else" part of "else if" inherently includes the condition that the order total is not greater than 1000. So we write our rules like this instead:
rule "15% discount"
when
$o : Order( total >= 1000, discount == null )
then
modify($o) { setDiscount(.15); }
end
rule "10% discount"
when
$o : Order( total >= 500, total < 1000, discount == null )
then
modify($o) { setDiscount(.10); }
end
rule "5% discount"
when
$o : Order( total >= 250, total < 500, discount == null )
then
modify($o) { setDiscount(.05); }
end
rule "no discount"
when
$o : Order( total < 250, discount == null )
then
modify($o) { setDiscount(0); }
end
(You'll notice I also added a discount == null
condition. This is to prevent the rule from reactivating when the Order fact is updated.)
I've been focusing on a simple example rather than your specific use case to demonstrate the concept of writing a condition to mimic an "else". I'm still not sure I completely understand your use case, but hopefully I've answered the key conceptual part of your question.
Pankaj Chaswal
Updated on June 04, 2022Comments
-
Pankaj Chaswal about 2 years
I am a newbie with Jboss Rule. I have gone through the documentation but I fail to find the approach to begin writing rule for following code sample.
For each User code in the list { If User code = ‘11’ { If User code ‘17’ present in the group { Add letter id 1 } Else If User code ‘18’ present in the group { Add letter id 2 } } Else { Add letter id 3 which is the letter need to be sent for code 11 } }
EDIT:
So far this is what i can develop for the user case discussed above.
- I am inserting (List of
UserDetailVo
) to the drools session. - Object (
UserDetailVo
) contains (List ofUserInfoVo
). EveryUserInfoVo
contains a code.
Now I want to iterate over the (List of
UserInfoVo
) and update (letterId
) to every (UserDetailVo
) as i am trying to do below.Case1 : when codeList has 110,121
rule "USER LETTER GROUPING 110,121" salience 300 no-loop true when userDetailVo : UserDetailVo () UserInfoVo(code=="110") from userDetailVo.codeList UserInfoVo(code=="121") from userDetailVo.codeList then userDetailVo.addLetterId(1); //modify(trrDetailRequestVo) end
Case2 : when codeList has 110,127
rule "USER LETTER GROUPING 110,127" salience 300 no-loop true when userDetailVo : UserDetailVo () UserInfoVo(code=="110") from userDetailVo.codeList UserInfoVo(code=="127") from userDetailVo.codeList then userDetailVo.addLetterId(2); //modify(trrDetailRequestVo) end
Case3 : when codeList has only 110
rule "USER LETTER GROUPING 110" salience 300 no-loop true when userDetailVo : UserDetailVo (this.letterID.size() == 0) // Checking size of the list UserInfoVo(code=="110") from userDetailVo.codeList then userDetailVo.addLetterId(3); //modify(trrDetailRequestVo) end
Issues that I am facing is if I user modify/update at the end of rule. It goes into an infinite loop. If I remove modify/update, in case 3 though list size if greater than 0 still rule is fired.
- I am inserting (List of