Search code examples
javadrools

Drools: Match local string from array in LHS of rule


I am trying to create rules in which I check if a string is in a list of strings in the LHS of my rule. The list of strings to compare to is constant and known at the time of rule creation, but differs among many similar rules.

An example rule is as such (the way I am writing them now):

rule "ruleX"
when
    $a: MyObject() 
then
    List<String> list = new ArrayList<String>();
    list.add("ABC");
    list.add("DEF");

    if (list.contains($a.getString()) {
        //do stuff
    }
end

This will not take advantage of the some of the optimizations present in the PHREAK engine, because there is work done in the RHS that could be used to distinguish rules via the LHS.

The contents of "list" vary over many of these similar rules. Is there a better way to do this? I can't imagine that a LAN database call would be faster.


Solution

  • This could be rewritten simply as:

    rule "ruleX"
    when
        MyObject( string in ("ABC", "DEF") ) 
    then
        //do stuff
    end
    

    Note that the list after in could also contain (previously) bound variables.

    If you have the values in a collection, you can also write

    rule "ruleY"
    when
        Data( $los: listOfStrings )
        MyObject( string memberOf $los ) 
    then
        //do stuff
    end
    rule "ruleY"
    when
        MyObject( $s: string ) 
        Data( listOfStrings contains $s )
    then
        //do stuff
    end
    

    This might be preferable if the lists can be extracted from somewhere (e.g. a DB) and wrapped into suitable facts, to be inserted up front.

    Note that the technical details are well documented in the Drools reference manual.