问题
Given a collection of BMSContract objects in memory of two or more, I need to match specific patterns using the BMSContract.status field. My rule should resolve to Success if in such collection exactly ONE and ONLY ONE BMSContract has a status of ACTIVE. Any other combination of objects and status codes should resolve to Fail. Again this rule is for a collection of 2 or more objects only and there could be any number of them: 2, 5, 10, 15 or more. There is a slightly different set of rules governing single BMSContract records. These rules are specific just to the multiple records scenarios such as these:
Case1 - Success
BMSContract(status=ACTIVE)
BMSContract(status=PENDING)
Reason: only one Active in the collection
Case2 - Success
BMSContract(status=ACTIVE)
BMSContract(status=PENDING)
BMSContract(status=HOLD)
Reason: only one Active in the coll
Case3 - Success
BMSContract(status=ACTIVE)
BMSContract(status=PENDING)
BMSContract(status=HOLD)
BMSContract(status=CANCEL)
Reason: only one Active in the coll
Case4 - Failure
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
Reason: too many Active records in coll
Case5 - Failure
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
Reason: too many Active records in coll
Case6 - Failure
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
BMSContract(status=ACTIVE)
Reason: too many Active records in coll
Case7 - Failure
BMSContract(status=PENDING)
BMSContract(status=HOLD)
BMSContract(status=OTHER)
Reason: No Active records in coll
回答1:
Given that you have a number of BMSContract
facts, the following rules would be enough:
rule OK
when
$ac: BMSContract( status == "ACTIVE" )
not BMSContract( this != $ac, status == "ACTIVE" )
then
// there is exactly one ACTIVE
end
rule not_OK_1
when
not BMSContract( status == "ACTIVE" )
then
// there is no ACTIVE
end
rule not_OK_2
when
$ac: BMSContract( status == "ACTIVE" )
exists BMSContract( this != $ac, status == "ACTIVE" )
then
// there is more than one ACTIVE
end
Variants are possible and may be required if you need to identify the facts that cause trouble:
rule not_OK_2a
when
$ac1: BMSContract( status == "ACTIVE" )
$ac2: BMSContract( this != $ac, status == "ACTIVE" )
then
// log and retract $ac2
end
来源:https://stackoverflow.com/questions/47211825/how-can-i-match-on-multiple-objects-of-the-same-kind-in-drools-5