如何在流口水规则引擎中处理列表项中对象的先前值?

Posted

技术标签:

【中文标题】如何在流口水规则引擎中处理列表项中对象的先前值?【英文标题】:How to process Previous value of object in list item in drool rule engine? 【发布时间】:2017-08-11 09:29:09 【问题描述】:

我希望 Drool 在列表的所有元素中触发规则

这是我的订单类

package com.sample;

import java.util.ArrayList;
import java.util.List;

public class Order 

    public static final int ORDER_AMOUNT_LIMIT = 10;
    public static final int DEFAULT_VALUE=0;

    public int id  ;
    public String name;
    public OrderItem item;
    public String code;
    public List<String> message=new ArrayList<String>();

    public void addmessage(String m) 
        message.add(m);
    




    public String getCode() 
        return code;
    
    public void setCode(String code) 
        this.code = code;
    

    public List<OrderItem> orderItems = new ArrayList<OrderItem>();

    public OrderItem getItem() 
        return item;
    
    public void setItem(OrderItem item) 
        this.item = item;
    
    Order(int id,String name)
        this.id = id;
        this.name =  name;
    
    public int getId() 
        return id;
    
    public void setId(int id) 
        this.id = id;
    
    public String getName() 
        return name;
    
    public void setName(String name) 
        this.name = name;
    

    public void addOrderItem(OrderItem item) 
        orderItems.add(item);



OrderItem.java

package com.sample;

import java.util.ArrayList;
import java.util.List;

public class OrderItem 

    public static final int TEMP_PRICE = 0; 

    public Order order;
    public int price;
    public String code;
    public List<String> message=new ArrayList();

    public  void addMessage(String msg)
        message.add(msg);
    


    public String getCode() 
        return code;
    

    public void setCode(String code) 
        this.code = code;
    

    OrderItem(Order order,int price)
        this.order = order;
        this.price = price;
    

    public Order getOrder() 
        return order;
    

    public void setOrder(Order order) 
        this.order = order;
    

    public int getPrice() 
        return price;
    

    public void setPrice(int price) 
        this.price = price;
    




order.drl

 package com.sample
import com.sample.Order;

rule "order"
when
    $order : Order()
     $total : Double() from accumulate( OrderItem( order == $order, $price : price,code == $order.code,),
                              sum( $price ) )


   eval($total>Order.ORDER_AMOUNT_LIMIT)
then
   System.out.println($total);
   $order.orderItems.get(0).price=0;

   System.out.println("price is "+ $order.orderItems.get(0).getPrice());
end

DroolTest.java

public class DroolsTest 

    public static final void main(String[] args) 
        try 
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            KieSession kSession = kContainer.newKieSession("ksession-rules");


            Order order =  new Order(1,"bob");
            order.setCode("test1");

            OrderItem item1 =  new OrderItem(order, 11);
            item1.setCode("test1");
            OrderItem item2 =  new OrderItem(order, 7);
            item2.setCode("test1");

            order.addOrderItem(item1);
            order.addOrderItem( item2 );


            kSession.insert(order);
            kSession.insert(item1);

            kSession.fireAllRules();


            kSession.insert(item2);
            kSession.fireAllRules();            

         catch (Throwable t) 
            t.printStackTrace();
        
    


输出

11.0
price is 0

如您所见,then 条件仅执行一次,因为 当流口水检查 11 > 10 工作正常并将值设置为 0 但现在当流口水处理第二个列表项时 sum 将返回 0+7 > 10 这是错误的,但我想在第二个列表中触发然后条件 item 因为 11+7 = 19 大于 10 有什么办法可以开火 那么两个列表项的条件?有什么办法让我们得到 对象的原始值不是来自工作内存?

【问题讨论】:

【参考方案1】:

您添加了一个模式 OrderItem,因此规则将针对超出限制的订单中的每个项目触发。

rule "order"
when
  $order: Order( $code: code )
  accumulate( OrderItem( order == $order, $price: price,
                         code == $code );
              $total: sum( $price );
              $total > Order.ORDER_AMOUNT_LIMIT )
  $item: OrderItem( order == $order, $price: price, code == $code )
then
   System.out.println( $item ); // an order item of a "big" order

end

【讨论】:

以上是关于如何在流口水规则引擎中处理列表项中对象的先前值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 的列表项中调用完成处理程序?

如何在由前一个元素的连续值和第二项中的零组成的列表中添加连续元素?

Drools规则引擎-如果判断某个对象中的集合是否包含指定的值

我们如何编写警报规则与普罗米修斯警报规则的先前值进行比较

规则引擎 clara-rules

使用junit进行流口水测试