Let’s analyze a simple rule:

rule "Simple order condition"
     when $o: Order()

The rule is defined in such a way that if we insert 50 orders, we will trigger this rule 50 times when we fire the rules. This is useful when we want to do something on each element that matches a condition. However, if we want to act against all the elements that match a condition at once, we need an extra syntax to help us. This is where the collect keyword comes into play.

The “collect” keyword is used to find all the elements that match a specific condition and group them into a collection. Later on, this collection can be assigned to a variable or submitted to further conditions, as follows:

rule "Grouping orders"
     when $list: List() from collect(Order())
          System.out.println("we've found " +$list.size() + " orders");

In the previous case, if we insert 50 orders and then fire the rules, the rule will fire only once, producing a list of 50 orders. However, if we fire all the rules without inserting any orders first, this rule would still fire returning an empty list in the $list variable. To avoid so, we should add conditions in the List object by writing it as follows:

$list: List(size > 0) from collect(Order())

The collect keyword can be combined with the from clause to create new collections from different sources. It is very useful whenever we can find objects through the rule conditions and add them directly to a collection.

Note: in Streamx the rules are fired automatically based on some thresholds (time, number of objects inserted, etc). So the $list will contain Orders inserted in between.