Drools Rule Language 学习笔记

Drools Rule Language

1 Packages in DRL

  • 可以有多个packages
  • 但推荐只用一个package
  • example: package org.mortgages;

2 Import statements in DRL

2.1 You specify the package and data object in the format packageName.objectName, with multiple imports on separate lines.

2.2 example: import org.mortgages.LoanApplication;

3 Functions in DRL

3.1 在drl里面定义函数

java 复制代码
	function String hello(String applicantName) {
    return "Hello " + applicantName + "!";
}

3.2 实际也可以直接import java 的static function: import static org.example.applicant.MyFunctions.hello;

4 Queries in DRL

查询fact,其实可以用java访问替代

4.1 Queries in DRL files search the working memory of the Drools engine for facts related to the rules in the DRL file

4.2 not yet supported

  • Expression unification - pred( X, X + 1, X * Y / 7 )
  • List and Map unification

4.3 支持对入参的赋值

java 复制代码
query contains(String $s, String $c)
    $s := String( this.contains( $c ) )
end

rule PersonNamesWithA when
    $p : Person()
    contains( $p.name, "a"; )
then
end

5 Type declarations and metadata in DRL

5.1 在DSL里面定义数据类型

5.1.1 支持extend,java访问

5.2 是否有实际应用场景?

Rule attributes in DRL

6.1 Rule attributes

6.1.1 salience 优先级

6.1.2 enabled

6.1.3 date-effective

  • 注意没有时间
  • Example: date-effective "4-Sep-2018"

6.1.4 date-expires

6.1.5 no-loop

  • 不重复执行 the rule cannot be reactivated (looped) if a consequence of the rule re-triggers a previously met condition.

6.1.6 agenda-group

就是分组,通过setFocus指定优先执行,具体看drools engine里面的说明

6.1.7 activation-group :only one rule can be activated

6.1.8 duration 执行时长:A long integer value defining the duration of time in milliseconds after which the rule can be activated, if the rule conditions are still met.

6.1.9 timer

  • 定时执行定义
  • Example: timer ( cron:* 0/15 * * * ? ) (every 15 minutes)

6.1.10 calendar

A Quartz calendar definition for scheduling the rule.

6.1.11 auto-focus

a focus is automatically given to the agenda group to which the rule is assigned

6.1.12 lock-on-active

  • 只用于agenda group 或者rule flow
  • the rule cannot be activated again until the ruleflow group is no longer active or the agenda group loses the focus

6.1.13 ruleflow-group

rules can fire only when the group is activated by the associated rule flow(纯规则不用,和jbpm有关)

6.1.14 dialect

A string identifying either JAVA or MVEL as the language to be used the dialect "JAVA" rule consequences support only Java 5 syntax

6.2 定时控制

6.2.1 Generally, a rule that is controlled by a timer becomes active when the rule is triggered and the rule consequence is executed repeatedly

6.2.2 When the Drools engine is in passive mode, rule consequences of timed rules are evaluated only when fireAllRules() is invoked again

6.2.3 可以通过ksconf.setOption( TimedRuleExecutionOption.YES );触发定时执行

java 复制代码
// You can additionally set a FILTERED specification on the TimedRuleExecutionOption option 
KieSessionConfiguration ksconf = KieServices.Factory.get().newKieSessionConfiguration();
conf.setOption( new TimedRuleExecutionOption.FILTERED(new TimedRuleExecutionFilter() {
    public boolean accept(Rule[] rules) {
        return rules[0].getName().equals("MyRule");
    }
}) );

7 Rule conditions in DRL (WHEN)

7.1 also known as the Left Hand Side (LHS) of the rule

7.2 每一行代表一个判断,默认连接词为and

7.3 defined keyword conjunctions (such as and, or, or not)

7.4 支持nest access properties in patterns

  • Person( address.houseNumber == 50 )
  • Person( getAddress().getHouseNumber() == 50 )
    7.5 example
  • Person( age > 100 && ( age % 10 == 0 ) )
  • Person( Math.round( weight / ( height * height ) ) < 25.0 )
  • Person( ( age > 50 && weight > 80 ) || height > 2 )

7.6 注意点

7.6.1 避免修改fact

7.6.2 避免随机fact

7.7 Bound variables in patterns and constraints

7.7.1 Bound variables can help you define rules more efficiently or more consistently with how you annotate facts in your data model.

7.7.2 绑定pattern

java 复制代码
rule "simple rule"
  when
    $p : Person()
  then
    System.out.println( "Person " + $p );
end

A pattern in a DRL rule condition is the segment to be matched by the Drools engine.

7.7.3 bind variables to properties in pattern constraints

// Two persons of the same age:

java 复制代码
Person( $firstAge : age ) // Binding
Person( age == $firstAge ) // Constraint expression

7.8 Nested constraints and inline casts

  • Person( name == "mark", address.( city == "london", country == "uk") )
  • Person( name == "mark", address.city == "london", address.country == "uk" )
  • inner class,使用#,例子
    Person( name == "mark", address#LongAddress.country == "uk" )

7.9 Date literal in constraints

7.9.1 By default, the Drools engine supports the date format dd-mmm-yyyy

7.9.2 修改:drools.dateformat="dd-mmm-yyyy hh:mm"

7.9.3 Person( bornBefore < "27-Oct-2009" )

7.10 Supported operators in DRL pattern constraints

7.10.1 .(), #

7.10.2 !. (interpreted as != null)

  • Person( $streetName : address!.street )

  • Person( address != null, $streetName : address.street )

7.10.3 []

operator to access a List value by index or a Map value by key.

7.10.4 <, <=, >, >=

7.10.5 ==, !=

7.10.6 &&, ||

7.10.7 matches, not matches

  • matches or does not match a specified Java regular expression

7.10.8 contains, not contains

7.10.9 memberOf, not memberOf

  • a field is a member of or is not a member of an Array or a Collection

7.10.10 soundslike

  • verify whether a word has almost the same sound, using English pronunciation,

7.10.11 str

  • starts with or ends with a specified value.
  • You can also use this operator to verify the length of the String.
java 复制代码
// Verify what the String starts with:
Message( routingValue str[startsWith] "R1" )

// Verify what the String ends with:
Message( routingValue str[endsWith] "R2" )

// Verify the length of the String:
Message( routingValue str[length] 17 )

7.10.12 in, notin

  • Color( type in ( "red", "blue", $color ) )

7.10.13 列表

7.11 supports the following rule condition elements (keywords)

7.11.1 and

  • Color( colorType : type ) and Person( favoriteColor == colorType )

7.11.2 or

注意可以不同对象之间or

java 复制代码
pensioner : (Person( sex == "f", age > 60 ) or Person( sex == "m", age > 65 ))
//Infix `or`:
Color( colorType : type ) or Person( favoriteColor == colorType )


//Infix `or` with grouping:
(Color( colorType : type ) or (Person( favoriteColor == colorType ) and Person( favoriteColor == colorType ))

// Prefix `or`:
(or Color( colorType : type ) Person( favoriteColor == colorType ))

7.11.3 exists

  • exists (Person( firstName == "John" ) and Person( lastName == "Doe" ))

7.11.4 not

7.11.5 not/forall

循环,整体判断

java 复制代码
rule "All full-time employees have red ID badges"
  when
    forall( $emp : Employee( type == "fulltime" )
                   Employee( this == $emp, badgeColor = "red" ) )
  then
    // True, all full-time employees have red ID badges.
end
rule "Not all employees have health and dental care"
  when
    not ( forall( $emp : Employee()
                  HealthCare( employee == $emp )
                  DentalCare( employee == $emp ) )
        )
  then
    // True, not all employees have health and dental care.
end

7.11.6 from

Use this to specify a data source for a pattern

java 复制代码
rule "Validate zipcode"
  when
    Person( $personAddress : address )
    Address( zipcode == "23920W" ) from $personAddress
  then
    // Zip code is okay.
end

Using from with lock-on-active rule attribute can result in rules not being executed

java 复制代码
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 the person.
end

The pattern that contains a from clause cannot be followed by another pattern starting with a parenthesis

7.11.7 entry-point

Use this to define an entry point, or event stream

java 复制代码
rule "Authorize withdrawal"
  when
    WithdrawRequest( $ai : accountId, $am : amount ) from entry-point "ATM Stream"
    CheckingAccount( accountId == $ai, balance > $am )
  then
    // Authorize withdrawal.
end
KieSession session = ...

// Create a reference to the entry point:
EntryPoint atmStream = session.getEntryPoint("ATM Stream");

// Start inserting your facts into the entry point:
atmStream.insert(aWithdrawRequest);

7.11.8 collect

java 复制代码
import java.util.List

rule "Raise priority when system has more than three pending alarms"
  when
    $system : System()
    $alarms : List( size >= 3 )
              from collect( Alarm( system == $system, status == 'pending' ) )
  then
    // Raise priority because `$system` has three or more `$alarms` pending.
end

7.11.9 accumulate

  • accumulate :These functions accept any expression as input.
  • average
  • min
  • max
  • count
  • sum
  • collectList
  • collectSet
java 复制代码
rule "Average profit"
  when
    $order : Order()
    accumulate( OrderItem( order == $order, $cost : cost, $price : price );
                $avgProfit : average( 1 - $cost / $price ) )
  then
    // Average profit for `$order` is `$avgProfit`.
end
  • 可以自定义,增加accumulate函数:create a Java class that implements the org.kie.api.runtime.rule.AccumulateFunction interface. alternate syntax for a single function with return type
java 复制代码
rule "Apply 10% discount to orders over US$ 100,00"
when
    $order : Order()
    $total : Number( doubleValue > 100 )
             from accumulate( OrderItem( order == $order, $value : value ),
                              sum( $value ) )
then
    // apply discount to $order
end
  • accumulate with inline custom code
java 复制代码
<result pattern> from accumulate( <source pattern>,
                                  init( <init code> ),
                                  action( <action code> ),
                                  reverse( <reverse code> ),
                                  result( <result expression> ) )
rule R

example

java 复制代码
dialect "mvel"
when
    String( $l : length )
    $sum : Integer() from accumulate (
                           Person( age > 18, $age : age ),
                           init( int sum = 0 * $l; ),
                           action( sum += $age; ),
                           reverse( sum -= $age; ),
                           result( sum )
                     )
eval

7.12 OOPath syntax with graphs of objects in DRL rule conditions

7.12.1 OOPath是XPath的面向对象语法扩展,用于浏览DRL规则条件约束下的对象。

7.12.2 对比

java 复制代码
rule "Find all grades for Big Data exam"
  when
    $student: Student( $plan: plan )
    $exam: Exam( course == "Big Data" ) from $plan.exams
    $grade: Grade() from $exam.grades
  then
    // Actions
end

Example rule that browses a graph of objects with OOPath syntax

java 复制代码
rule "Find all grades for Big Data exam"
  when
    Student( $grade: /plan/exams[course == "Big Data"]/grades )
  then
    // Actions
end

7.12.3 语法

  • OOPExpr = [ID ( ":" | ":=" )] ( "/" | "?/" ) OOPSegment { ( "/" | "?/" | "." ) OOPSegment } ;
  • OOPSegment = ID ["#" ID] ["[" ( Number | Constraints ) "]"]

examples

java 复制代码
Student( $grade: /plan/exams#AdvancedExam[ course == "Big Data", level > 3 ]/grades )
Student( $grade: /plan/exams/grades[ result > ../averageResult ] )

/和?/区别

  • Slash ("/"): Used as a separator in the path expression.
  • Question Mark ("?"): Used as a wildcard to match any object in a collection.
  • Forward Slash with Question Mark ("?/"): Used for nested wildcard matching in collections.
    7.12.4 参考URL
    https://blog.csdn.net/u010952582/article/details/109669747

8 Rule actions in DRL (THEN)

8.1 The then part of the rule (also known as the Right Hand Side (RHS) of the rule) contains the actions to be performed when the conditional part of the rule has been met.

8.2 Supported rule action methods in DRL

8.2.1 java set

  • set ( )
  • $application.setApproved ( false );
    8.2.2 modify
    可以看着批量set,会触发rule
java 复制代码
modify( LoanApplication ) {
        setAmount( 100 ),
        setApproved ( true )
}

8.2.3 update

  • 通知drools fact 有变化
  • update ( <object, ) // Informs the Drools engine that an object has changed
java 复制代码
LoanApplication.setAmount( 100 );
update( LoanApplication );

8.2.4 insert-参考engine

  • insert
  • insertLogical

8.2.5 delete

8.3 Other rule action methods from drools variable

使用drools获取当前runtime 信息

8.3.1 drools .getRule().getName(): Returns the name of the currently firing rule.

8.3.2 drools.getMatch(): Returns the Match that activated the currently firing rule.

8.3.3 drools.getKieRuntime().halt(): Terminates rule execution if a user or application previously called fireUntilHalt()

8.3.4 drools.getKieRuntime().getAgenda(): Returns a reference to the KIE session Agenda

8.3.5 具体参考java doc getRuleMatch/KieRuntime

8.4 Advanced rule actions with conditional and named consequences

8.4.1 使用DO 分支

8.4.2 使用break 分支

break blocks any further condition evaluation

java 复制代码
rule "Give free parking and 10% discount to over 60 Golden customer and 5% to Silver ones"
  when
    $customer : Customer( age > 60 )
    if ( type == "Golden" ) do[giveDiscount10]
    else if ( type == "Silver" ) break[giveDiscount5]
    $car : Car( owner == $customer )
  then
    modify($car) { setFreeParking( true ) };
  then[giveDiscount10]
    modify($customer) { setDiscount( 0.1 ) };
  then[giveDiscount5]
    modify($customer) { setDiscount( 0.05 ) };
end

9 Comments in DRL files

9.1 DRL supports single-line comments prefixed with a double forward slash // and multi-line comments enclosed with a forward slash and asterisk /* ... */

10 Error messages for DRL troubleshooting

10.1 图例

10.2 1st Block: Error code

10.3 2nd Block: Line and column in the DRL source where the error occurred

10.4 3rd Block: Description of the problem

10.5 4th Block: Component in the DRL source (rule, function, query) where the error occurred

10.6 5th Block: Pattern in the DRL source where the error occurred (if applicable)

10.7 error code

  • 10.7.1 101: no viable alternative
  • 10.7.2 102: mismatched input
  • 10.7.3 103: failed predicate
  • 10.7.4 104: trailing semi-colon not allowed: Indicates that an eval() clause in a rule condition uses a semicolon ; but must not use one.
    eval( abc(); ) // Must not use semicolon ;
  • 10.7.5 105: did not match anything

11 Rule units in DRL rule sets (实验性功能)

11.1 Rule units are groups of data sources, global variables, and DRL rules that function together for a specific purpose

11.2 Rule units are experimental in Drools 7. Only supported in Red Hat build of Kogito.

11.3 需要创建对应java class

11.3.1

11.3.2 package org.mypackage.myunit

java 复制代码
unit AdultUnit

rule Adult
  when
    $p : Person(age >= adultAge) from persons
  then
    System.out.println($p.getName() + " is adult and greater than " + adultAge);
end

12 Performance tuning considerations with DRL

12.1 Define the property and value of pattern constraints from left to right

12.1.1 ensure that the fact property name is on the left side of the operator and that the value (constant or a variable) is on the right side

12.2 Use equality operators more than other operator types in pattern constraints when possible

12.3 List the most restrictive rule conditions first

12.4 Avoid iterating over large collections of objects with excessive from clauses

12.5 Use Drools engine event listeners instead of System.out.println statements in rules for debug logging

12.6 Use the drools-metric module to identify the obstruction in your rules

  • first add drools-metric to your project dependencies:
  • If you want to use drools-metric to enable trace logging, configure a logger for org.drools.metric.util.MetricLogUtils
java 复制代码
  <logger name="org.drools.metric.util.MetricLogUtils" level="trace"/>
  • Alternatively, you can use drools-metric to expose the data using Micrometer.
    Example project dependency for Micrometer
java 复制代码
<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-jmx</artifactId> <!-- Discover more registries at micrometer.io. -->
</dependency>

Example Java code for Micrometer

java 复制代码
  Metrics.addRegitry(new JmxMeterRegistry(s -> null, Clock.SYSTEM));
相关推荐
青椒大仙KI1126 分钟前
24/9/19 算法笔记 kaggle BankChurn数据分类
笔记·算法·分类
liangbm31 小时前
数学建模笔记——动态规划
笔记·python·算法·数学建模·动态规划·背包问题·优化问题
GoppViper1 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
Charles Ray2 小时前
C++学习笔记 —— 内存分配 new
c++·笔记·学习
重生之我在20年代敲代码2 小时前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
我要吐泡泡了哦3 小时前
GAMES104:15 游戏引擎的玩法系统基础-学习笔记
笔记·学习·游戏引擎
骑鱼过海的猫1233 小时前
【tomcat】tomcat学习笔记
笔记·学习·tomcat
贾saisai5 小时前
Xilinx系FPGA学习笔记(九)DDR3学习
笔记·学习·fpga开发
北岛寒沫5 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
烟雨666_java5 小时前
JDBC笔记
笔记