Search code examples
javadroolsrule-engine

Check for specific element in a list in Drools


I just have started using Drools (version 5.1.0) so please bear with me in case this question was already answered.

I have a java.util.List object which contains objects of complex type A, with A as:

class A {
  String name; 
  String Value;}

The list as well as its elements are in the working memory of the Drools engine. Is there an easy way to fire a rule only if the name and value of an element in the list are matching specific values?

Currently, i am using a self-defined function inside the Drools rule, which iterates over the list and returns true if there is an element that matches the specification, however i wonder whether this is the most efficient and easiest use.


Solution

  • If the A instances are in the working memory as you say (ideal scenario), just write the rule using it:

    rule X
    when
        A( name == "bob", value == 10 )
    ...
    

    Inserting collections (lists, trees, etc) into the working memory directly is not recommended, because they are abstract data structures without any intrinsic semantic attached. But lets say you have a Person class, that contains a list of Addresses, and you want to execute the rule for each address in Montreal, Canada, without inserting the addresses themselves as facs. You can write:

    rule X
    when
        Person( $addresses : addresses )
        Address( city == "Montreal", country == "CA" ) from $addresses
    ...
    

    Finally, if you really want to use the list itself as a fact (again, bad practice), you can do the following, but note that it will match all lists in the working memory:

    rule X
    when
        $list : List()
        A( name == "bob", value == 10 ) from $list
    ...