Drools Expression 介绍

用好Drools 中的表达式是你的规则引擎能否强大的必要条件

http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html

下面列出了几个个人认为比较重要的点: 

 

AND 

Drools 默认的并列表达式就是 前置的AND

(and Cheese( cheeseType : type )      
    Person( favouriteCheese == cheeseType ) )

when     Cheese( cheeseType : type )     
        Person( favouriteCheese == cheeseType )
 then     ...    

 

 OR

 OR 实际上并不是按照||的短路逻辑进行处理的, 而是将一个规则写为两个子规则, 分别匹配和执行

(or Person( sex == "f", age > 60 )     Person( sex == "m", age > 65 )
pensioner : ( Person( sex == "f", age > 60 ) or Person( sex == "m", age > 65 ) )

(or pensioner : Person( sex == "f", age > 60 )      pensioner : Person( sex == "m", age > 65 ) )

 

NOT

there must be none of...

相当于work memory必须没有所示表达式的对象, 建议写()

// Brackets are optional:
not Bus(color == "red")
// Brackets are optional:
not ( Bus(color == "red", number == 42) )
// "not" with nested infix and - two patterns,
// brackets are requires:
not ( Bus(color == "red") and
      Bus(color == "blue") ) 

 

EXIST 

there is at least one..

相当于work memory至少有一个所示的对象

exists Bus(color == "red")
// brackets are optional:
exists ( Bus(color == "red", number == 42) )
// "exists" with nested infix and,
// brackets are required:
exists ( Bus(color == "red") and
         Bus(color == "blue") )

 

FORALL

WorkMemory中所有facts都需要符合表达式, 可以支持多项匹配

单项匹配

rule "All Buses are Red"
when
    forall( Bus( color == 'red' ) )
then
    // all Bus facts are red
end

 

多项顺序匹配, 所有英文的bus都是红色的

rule "All English buses are red"
when
    forall( $bus : Bus( type == 'english') 
                   Bus( this == $bus, color = 'red' ) )
then
    // all English buses are red
end

更复杂的情况, 所有employee都有health和dental care

rule "all employees have health and dental care programs"
when
    forall( $emp : Employee()
            HealthCare( employee == $emp )
            DentalCare( employee == $emp )
          )
then
    // all employees have health and dental care
end

 

 FROM

从fact中拿出匹配表达式的field, 支持 基本类型 和 集合类, 如果是集合类且有多个符合条件的field, rule会fire多次

 

rule "apply 10% discount to all items over US$ 100,00 in an order"
when
    $order : Order()
    $item  : OrderItem( value > 100 ) from $order.items
then
    // apply discount to $item
end

 只要value>100就会被fire一次, 相当于   遍历items, 判断并执行   for item in items: if value > 100 then ....

 

rule "Assign people in North Carolina (NC) to sales region 1"
ruleflow-group "test"
lock-on-active true
when
    $p : Person( ) 
    $a : Address( state == "NC") from $p.address 
then
    modify ($p) {} // Assign person to sales region 1 in a modify block
end

rule "Apply a discount to people in the city of Raleigh"
ruleflow-group "test"
lock-on-active true
when
    $p : Person( ) 
    $a : Address( city == "Raleigh") from $p.address 
then
    modify ($p) {} // Apply discount to person in a modify block
end

如果person在Raleign, NC生活, 应该两个rule都被Fire, 实际上, 只有第二个rule被fire, 原因是lock-on-active 当一系列fact变化时,  阻止rule进行新的activition, 所以第一个rule没有被再次active, 如果没有fact发生变化, 则一切正常

 

 注意点:

  • Avoid the use of from when you can assert all facts into working memory or use nested object references in your constraint expressions (shown below).

  • Place the variable assigned used in the modify block as the last sentence in your condition (LHS).

  • Avoid the use of lock-on-active when you can explicitly manage how rules within the same rule-flow group place activations on one another (explained below).

 

Accumulate

将WorkMemory中的每个fact中的值进行累加操作, 内嵌支持min max avg count sum collectList collectSet, 也可以自己实现org.drools.core.runtime.rule.TypedAccumulateFunction接口, 从而写出自己的accumulate 函数

rule "Raise alarm"
when
    $s : Sensor()
    accumulate( Reading( sensor == $s, $temp : temperature );
                $min : min( $temp ),
                $max : max( $temp ),
                $avg : average( $temp );
                $min < 20, $avg > 70 )
then
    // raise the alarm
end

 

Eval
用于接受boolean值

 

其他注意点:

ruleflow-group

default value: N/A

type: String

Ruleflow is a Drools feature that lets you exercise control over the firing of rules. Rules that are assembled by the same ruleflow-group identifier fire only when their group is active.

规则流是一个Drools的功能,让你在规则的fire进行控制。即用相同的规则流组只有当他们的group active时才会被fire。

 

agenda-group
default value: MAIN

type: String

Agenda groups allow the user to partition the Agenda providing more execution control. Only rules in the agenda group that has acquired the focus are allowed to fire.

Agenda 允许用户进行分区并提供更多的执行控制。只有在 agenda group 被focus的时候才可以被fire

 

auto-focus
default value: false

type: Boolean

When a rule is activated where the auto-focus value is true and the rule's agenda group does not have focus yet, then it is given focus, allowing the rule to potentially fire.

可以让没有被focus的 agenda group获得 focus, 允许rule去执行

 

activation-group
default value: N/A

type: String

Rules that belong to the same activation-group, identified by this attribute's string value, will only fire exclusively. More precisely, the first rule in an activation-group to fire will cancel all pending activations of all rules in the group, i.e., stop them from firing.

Note: This used to be called Xor group, but technically it's not quite an Xor. You may still hear people mention Xor group; just swap that term in your mind with activation-group.

属于activation-group的rules将进行 独占式的触发, 更准确地说,一个已被fire的规则可以阻止所有的未执行规则

 

date-effective

default value: N/A

type: String, containing a date and time definition

A rule can only activate if the current date and time is after date-effective attribute.

一个rule只能在当前时间或者当前时间之后被触发

 

date-expires
default value: N/A

type: String, containing a date and time definition

A rule cannot activate if the current date and time is after the date-expires attribute.

一个rule不能在当前时间或者当前时间之后被触发

 

duration

default value: no default value

type: long

The duration dictates that the rule will fire after a specified duration, if it is still true.

rule将在duration时间之后被fire

posted @ 2014-10-24 17:28  zhwbqd  阅读(2103)  评论(0编辑  收藏  举报