Reputation: 932
I want to check if any item from a list of diagnosis codes exists in another list.
I am new to Drools and I'm still trying to decide on the best approach as the current one isn't working (the output says null when it should be returning 'true').
Java POJO
public class EligibilityDomainObject {
private List<String> listOfString;
public List<String> getListOfString() {
return listOfString;
}
public void setListOfString(List<String> listOfString) {
this.listOfString = listOfString;
}
public void addString(String value) {
if (listOfString == null) {
listOfString = new ArrayList<String>();
}
listOfString.add(value);
}
private Boolean isComplexPhysicalHealth;
public Boolean getIsComplexPhysicalHealth() {
return this.isComplexPhysicalHealth;
}
public void setIsComplexPhysicalHealth(Boolean isComplexPhysicalHealth) {
this.isComplexPhysicalHealth = isComplexPhysicalHealth;
}
Drools
rule "Problems related to social environment"
when
$eligibilityDomainObject:EligibilityDomainObject($listOfString : listOfString,
$listOfString memberOf "F77 EOO F99" )
then
$eligibilityDomainObject.setIsComplexPhysicalHealth(true);
end
Main
public static void main(String[] args) {
SpringApplication.run(RulesEngineApplication.class, args);
try {
KieServices kieServices = KieServices.Factory.get();
KieContainer kContainer = kieServices.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
EligibilityDomainObject eligibilityDomainObject = new EligibilityDomainObject(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
eligibilityDomainObject.addString("F77");
eligibilityDomainObject.addString("F99");
System.out.println("List of diagnosis codes: "+ eligibilityDomainObject.getListOfString().toString());
kSession.insert(eligibilityDomainObject);
kSession.fireAllRules();
System.out.println("complex phys health flag: "+ eligibilityDomainObject.getIsComplexPhysicalHealth());
kSession.dispose();
} catch (Throwable t) {
t.printStackTrace();
}
}
output
List of diagnosis codes: [Z590, E0800]
complex phys health flag: null
expected output
List of diagnosis codes: [Z590, E0800]
complex phys health flag: true
Upvotes: 1
Views: 264
Reputation: 20966
Your rule will misbehave against 'F', 'F7', 'F9'...
Consider few other approaches:
rule "Problems related to social environment"
when
$eligibilityDomainObject:EligibilityDomainObject($listOfString : listOfString)
value: String(value in ("F77", "EOO", "F99") ) from $listOfString
then
$eligibilityDomainObject.setIsComplexPhysicalHealth(true);
end
According to documentation, one need to
Avoid using the from element when you can insert all facts into the working memory of the Drools engine or use nested object references in your constraint expressions."
Following will cause the rule to be triggered only once per EligibilityDomainObject, not per each matching value:
import static org.apache.commons.collections4.CollectionUtils.containsAny;
rule "Problems related to social environment"
when
$eligibilityDomainObject:EligibilityDomainObject(containsAny(listOfString, "F77", "EOO", "F99"))
then
$eligibilityDomainObject.setIsComplexPhysicalHealth(true);
end
gather matching values in one go
import static org.apache.commons.collections4.CollectionUtils.intersection;
import static com.google.common.collect.Sets.newHashSet;
rule "Problems related to social environment"
when
$eligibilityDomainObject:EligibilityDomainObject(
$values : intersection(listOfString, newHashSet("F77", "EOO", "F99")),
!$values.isEmpty())
then
$eligibilityDomainObject.setIsComplexPhysicalHealth(true);
System.out.println($values);
end
Upvotes: 1
Reputation: 932
I was able to solve it using the 'from' keyword
rule "Problems related to social environment"
when
$eligibilityDomainObject:EligibilityDomainObject($listOfString : listOfString)
value: String(value memberOf "F77 EOO F99" ) from $listOfString
then
$eligibilityDomainObject.setIsComplexPhysicalHealth(true);
end
Upvotes: 1