LHS (left hand side) 部分
Drools 作为规则引擎, 最重要的功能就是完成 pattern match, 即按照 LHS 对工作内存的fact进行匹配, 老版Drools使用的匹配算法是RETE(读音[reetee]), 该算法的核心策略是分而治之+以空间换时间, 基于该算法, 即使是有大量的rule和fact需要匹配, 规则执行的时间复杂度也是可以接受的, 当然内存占用会比较高.
完整的 LHS 语法比较复杂, 可参考Drools Documentation
但基本语法是非常简单, 一般情况下只需要基本语法就足够了.
绑定变量
下面就是一个常用的LHS, 包含两个关联对象的匹配, 定义了两个对象级别绑定变量, 一个属性级的绑定变量.
when
$customer:Customer(age>20 && location=="China" && gender=="male", $age:age)
$order: Order(customer==$customer, price>1000)
then
...
约束中的操作符:
约束中常用的操作符号有:
- < 和 <= 和 > 和 >= 符号, 这些与java含义一致, 可以对数值和字符串进行对比
- == , 这个是null安全的equal, 和java的 == 含义不同.
- !=, 这个是null安全的不等于符号, 和java中的 != 含义不同
- contains , 包含, 可以判断字符串包含子串, 也可以判断集合/数组包含元素
- not contains, 不包含
- memberOf, 属于, 注意
Of
要大写. 和 contains 语义正好相反. - not memberOf, 不属于,注意
Of
要大写. - matches, 正则匹配
- not matches, 正则不匹配
- instanceOf, 类型属于
- not instanceOf, 类型不属于
- in , 这个作用和 memberOf 类似, 写法同SQL的in子句
- not in, 这个和 not memberOf 类似, 写法同SQL的 not in 子句
- && ,逻辑与, 和java的含义
- || , 逻辑或, 和java的含义
逗号分隔符
逗号分隔符可以分隔两个条件, 其作用等同于 &&, 但优先级比较 && 和 || 要低, 一般情况下, 推荐使用逗号分隔符因为其可读性更好.
字符串专用运算符 str
$order:Order(name str[startsWith] "A")
$order:Order(name str[endsWith] "A")
$order:Order(name str[length] 15)
分组条件元素(conditional element)
分组条件元素不同于普通的操作符, 普通操作符用在field上, 而, 分组条件元素被用于外层的分组
上.
- and
and 分组条件元素的作用是逻辑连接
, 一般我们会省略这里的 and 关键词.
when
Cheese(type=="IceCream", $cheeseType:type)
and //这里的and可以被省略
Person(favoriteCheese==$cheeseType)
then
...
-
or
or 分组条件元素的作用是逻辑分离
, or 分组实用性不强, 在实际项目中并不常用到. -
exists
exists 是一元分组元素, 用于检查是否在working memory中存在. 如果某个对象在working memory中存在多个实例, exists 也仅仅会触发一次.
when
//触发一次
exists Order(qty>1000)
then
...
when
//触发多个
Order(qty>1000)
then
...
- not
not 也是一元分组元素, 用于检查是否在working memory中不存在, 含义正好和 exists 相反.
LHS 访问对象属性的方法
LHS访问对象属性可以使用field 名称也可以使用getter方法, 但更推荐直接使用field, 因为它可以利用上 drools 的field indexing, 有更好的性能.
Person(age>18) //age 属性
Person(address.houseNumber==50) //访问address子对象的属性
list 和 map 的访问
可以通过下标访问数组/list元素, 可以通过key访问map.
list示例: Person(childList[0].age==18)
list示例: Person(childMap["Allen"])