Dennis Liger
Dennis Liger

Reputation: 1516

Drools sequence of events with accumulate function

I would like to build the rule for following use case: I'm expecting two "AddToCart" events and then "Search" event, exactly in described sequence. P.S. this is not a real business use case.

Currently, I'm trying to achieve solution with the following rule:

rule "Rule-102"
salience 1000110000
    agenda-group "level0"
    dialect "mvel"
    when
         Number(doubleValue >= 2) from accumulate ($event1: Event(eval($event1.getName().equals('AddToCart'))),count($event1));$event: Event()
         $event2: Event(eval($event2.getName().equals('Search')), this after $event)
    then
        sendEvent($event2, ed, drools);
end

This rule works not correctly because sequence of events not defined properly: Search -> AddToShoppingCart -> AddToShoppingCart = Action

I want only strict sequence: AddToShoppingCart -> AddToShoppingCart -> Search = Action

Upvotes: 1

Views: 1020

Answers (1)

Esteban Aliverti
Esteban Aliverti

Reputation: 6322

If your rules involve a small set of patterns (in this case, 2 AddToCart and 1 Search) you could try something like this:

rule "Rule-102"
when
    $e1: Event(name == "AddToCart")
    $e2: Event(name == "AddToCart", timestamp > $e1.timestamp)
    $s1: Event(name == "Search", timestamp > $e2.timestamp)
then
    sendEvent($s1, ed, drools);
end

Despite being elegant, this solution has some potential problems:

  • It will not scale well if you want to use more AddToCart events.
  • If you have 3 (or more) AddToCart events this rule will fire multiple times (I'm not sure if this is the desired behavior in your use case)

If you want to use a more generic approach, you could try something along these lines:

rule "Rule-102"
when
    $s1: Event(name == "Search")
    Number(intValue >= 2) from accumulate(
        Event(name == "AddToCart", timestamp < $s1.timestamp),
        count(1)
    )
then
    sendEvent($s1, ed, drools);
end

Hope it helps,

Upvotes: 2

Related Questions