Skip to main content
The power of Drools lies in its ability to identify patterns in your data and respond accordingly. The condition section of your rules (the when part) is where you define these patterns. In this section, we’ll explore how to write effective, efficient rule conditions that accurately capture your business logic.

Understanding Pattern Matching

At the heart of Drools rule conditions is pattern matching. A pattern defines a template that the Drools rule engine uses to find matching facts in the working memory.

Basic Pattern Structure

The simplest pattern has this form:
For example:
This pattern matches all customer facts in the customers data source that have the status “GOLD”. To reference the matched object in other parts of the rule, you can bind it to a variable:
You can now use $customer in other patterns or in the rule’s actions.

OOPath Expressions

OOPath is a powerful feature in Drools that allows you to navigate through object graphs in a concise, elegant way. It’s inspired by XPath but adapted for object-oriented structures. Basic OOPath syntax:
For example, to match orders from a gold customer:
This navigates from customers to their orders, finding orders over $100 from gold customers. You can also bind variables at each step:
This approach is more explicit about the relationship between customers and orders, and it’s particularly useful when you need to reference both the customer and the order in your rule’s actions.

Writing Effective Constraints

Constraints are conditions that facts must satisfy to match a pattern. They filter the facts in your data sources to find those relevant to your rule.

Simple Constraints

Simple constraints compare a property to a value:

Multiple Constraints

You can combine multiple constraints using:
  1. Comma-separated list (implicit AND): /customers[ status == "GOLD", yearsSinceJoining > 5 ]
  2. Logical operators (&&, ||): /customers[ status == "GOLD" && (yearsSinceJoining > 5 || totalSpent > 10000) ]
The comma-separated approach is preferred for simple AND conditions as it’s more readable and slightly more efficient.

Constraint Operators

DRL supports a wide range of operators for constructing constraints:

Basic Comparison

String Matching

Collection Operations

Special Operators

Abbreviated Combined Relation Constraints

DRL provides a shorthand for range expressions:
This is equivalent to:
But offers a more concise syntax for ranges.

Property Access

You can access nested properties using the dot notation:
For null-safe property access, use the !. operator:
This will only match customers who have an address and whose zip code is “90210”.

Binding Variables

Variables are a crucial part of DRL. They allow you to:
  1. Reference matched facts in other patterns or in actions
  2. Access specific properties for later use
  3. Join patterns together

Basic Variable Binding

To bind a fact to a variable, use the : operator:
You can use $customer to reference this fact in other patterns:

Property Binding

You can also bind specific properties:
Now you can use $name and $age in your rule without accessing them through the customer object.

Best Practices for Variable Binding

  1. Use meaningful names: Choose variable names that reflect what they represent.
  2. Use the $ prefix: This is a convention that helps distinguish variables from properties.
  3. Separate bindings from constraints: For clarity, list bindings first, then constraints.
  4. Only bind what you need: Binding creates overhead, so only bind variables you’ll actually use.

Advanced Condition Elements

DRL provides several condition elements that allow you to express complex patterns of facts.

not

The not element matches when a pattern has no matches. It’s used to verify that something doesn’t exist:
This matches when there’s no blacklisted customer with the given name.

exists

The exists element matches when a pattern has at least one match. It’s used to verify that something exists:
This matches when the customer has placed at least one order this year.

and

The and element creates a logical conjunction of two or more patterns. It matches when all its contained patterns match:
This matches gold customers who have placed an order over $1000.

or

The or element creates a logical disjunction of two or more patterns. It matches when any of its contained patterns match:
This matches customers who are either gold status or silver status with more than 5 years of membership.

forall

The forall element matches when all facts matching the first pattern also match all the remaining patterns:
This matches when all business customers have had their credit checked.

The accumulate Function

The accumulate function allows you to perform calculations over groups of facts. This is similar to SQL’s aggregate functions but more powerful.

Basic Syntax

Predefined Accumulate Functions

Drools includes several built-in accumulate functions:

Constraints on Accumulated Results

You can add constraints on the results of accumulate functions:

Multiple Functions in One Accumulate

You can combine multiple functions in a single accumulate:

The groupby Function

The groupby function extends accumulate by allowing you to partition data based on keys and perform accumulate functions on each group.

Basic Syntax

Example

This will create groups based on product categories and calculate the total sales for each category.

Putting It All Together: Real-World Examples

Let’s look at some comprehensive examples that combine the concepts we’ve learned.

Example 1: Customer Loyalty Upgrade

This rule upgrades silver customers to gold status when they have:
  1. Spent at least $5,000 this year
  2. Placed at least 10 orders this year
  3. No open disputes

Example 2: Fraud Detection

This rule flags transactions as potentially fraudulent when:
  1. The transaction is high-value (over $1,000)
  2. The customer’s known location differs from the transaction location
  3. There have been multiple other substantial transactions in the last hour

Performance Considerations for Rule Conditions

Writing efficient rule conditions is crucial for good performance, especially with large fact bases.

Best Practices

  1. Most restrictive patterns first: Place patterns that will match the fewest facts first.
  2. Most restrictive constraints first: Within a pattern, place the most selective constraints first.
  3. Avoid unnecessary variable bindings: Only bind variables you’ll actually use.
  4. Use property reactivity: Only update the properties that have changed to avoid unnecessary rule reevaluation.
  5. Avoid complex expressions in constraints: Move complex calculations to helper methods.
  6. Be careful with not and exists: These can be expensive with large fact bases.
  7. Use indexing effectively: Properties used in join conditions should be indexed.

Common Pitfalls

  1. Expensive constraint evaluation: Avoid constraints that require costly computation.
  2. Cross-product joins: Be cautious with patterns that create large combinations of facts.
  3. Redundant rule activations: Use no-loop and lock-on-active attributes when appropriate.
  4. Overuse of eval: The eval condition element doesn’t use Drools’ optimizations.
  5. Memory leaks: Remove facts from working memory when they’re no longer needed.

Summary

Understanding rule conditions is essential for harnessing the full power of Drools. By mastering pattern matching, constraints, condition elements, and accumulation functions, you can express complex business logic in a declarative, maintainable way. The condition section is where you define what situations your rules respond to. Taking time to design these conditions carefully ensures your rules fire exactly when they should – no more, no less. In the next section, we’ll explore the action side of rules: what happens after your conditions are met.