Search code examples
drools

Drools DRL variable instantiation when using OR


I have the following rule condition

$entity: (Entity(field != null) or Entity(field == null))

If the drools session has these two facts

  1. Entity(field = null)
  2. Entity(field = "Some Value")

When I inspect $entity, which of the two is going to be there? The behavior I'm looking for is for $entity to store Entity(field = "Some value") if both facts are in session, is there a way to accomplish this?


Solution

  • The behavior I'm looking for is for $entity to store Entity(field = "Some value") if both facts are in session, is there a way to accomplish this?

    You'd do this by checking for both and then only keeping the one that you really want to be doing work on.

    rule "Example"
    when
      exists( Entity(field == null ) )
      $entity: Entity( field != null )
    then
      // ...
    end
    

    Here, the rule checks for the presence of an Entity that has no field value set using the exists operator. Exists, like it implies, only checks that a fact meets these criteria, but doesn't ever retain a reference to it.

    Then the second condition checks that an Entity exists that does have a field value set, and assigns it to $entity so it can be referenced in the consequences/right hand side/then clause.

    Only if both of these conditions are met will this rule trigger.


    Note that if you happen to have three facts in working memory like this:

    • A: Entity(field = null)
    • B: Entity(field = "ABC" )
    • C: Entity(field = "XYZ")

    ... then this rule will fire twice. It will trigger once for A+B and once for A+C. In both cases, the presence of fact A will satisfy the exists condition, but both B and C satisfy the second condition so will both independently trigger the rule.