4
votes

I have a drools question which has been troubling me for some time. I want to find out the min and max price from a list of Item objects (contains price) using accumulate. A Member object (which contails list of Item objects) is inserted which contains the list of Items.

groovy/java source pseudo code
-------------------------------
class Item {
   BigDecimal price
}

class Member {
   List<Item>> items
}

...
droolsStatefulSession.insert(member)
session.fireAllRules()
...

rule.drl
---------
rule "rule1"
when 
   member : Member ($itemList : items)
/*

*/
then
 System.out.println("condition met...")
end

Now the questions is in the above rule is it possible to if so how do I find out the item with the minimum Price and maximum price using drools accumulate feature. I do not want to use an java/groovy utility functions.

I see the "collect" feature allows to use "from" and then a datasource. I wonder if "accumulate" is similar to collect.

2

2 Answers

8
votes

No need to use accumulate, just do something like

Item($lowestPrice : price, $id : id)
not Item(price > $lowestPrice, id < $id)

That's if your Items are inserted into the working memory.

0
votes

I'm new to the drool rule and I'm trying to solve this issue.

You can find out min and max price of item simply - you have to write some rules and need to add two variable in the Order class:

Class Order
{
    private List<Item> itemList;
    private int highPrice;
    private int lowPrice;
}

Using the following rule you can calculate min and max value of an item:

package com.sample

import com.sample.DroolsTest.Message;

rule "rule1"

    when
        $order : Order($itemList:itemList)

         $item:Item() from $order.itemList
    then
              insertLogical($item);
    end

rule "highPriceRule"
    when
         $order : Order()

         $item:Item($price:price,price>=$order.getHighPrice())

    then
        $order.setHighPrice($item.getPrice());
end

rule "lowPriceRule"

    when

         $order : Order()


         $item:Item($price:price,price<=$order.getLowPrice()||$order.getLowPrice()==0)

    then

        $order.setLowPrice($item.getPrice());

end

rule "highPrice"

salience -1

    when

         $order : Order()

    then

        System.out.println( "higher Item Price is  "+$order.getHighPrice());

end
rule "LowPrice"
salience -1
    when
         $order : Order()
    then
        System.out.println( "Lower Item Price is  "+$order.getLowPrice());
end


in main method you have to write this code and run it


List<Item>  items=new ArrayList<Item>();

        Item item1=new Item();
        item1.setPrice(10);

        Item item2=new Item();
        item2.setPrice(20);


        Item item3=new Item();
        item3.setPrice(10);

        Item item4=new Item();
        item4.setPrice(5);

        items.add(item1);
        items.add(item2);
        items.add(item3);
        items.add(item4);


           Order order=new Order();
           order.setItemList(items);
            ksession.insert(order);
            ksession.fireAllRules();

output:---

Lower Item Price is  5


higher Item Price is  20

As I'm new to the drool rule I would like to ask if this is the correct procedure? Or is there another way to solve this problem?