How can i match on multiple objects of the same kind in Drools 5?

孤街醉人 提交于 2019-12-13 02:51:22

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!