如何在Drools 5.6规则中定义常量集合

时间:2015-08-07 04:35:57

标签: java drools

我正在使用Drools 5.6。我需要将Rules / KnowledgeBase提供给另一个系统。我的一些规则是一种ID过滤器。例如,用非法语法表示,它看起来像:

rule "X":
  when
    $fact: ToBeFilteredObject(this.getId() in [1, 2, 3, 4, 5, ...])
  then
    // do something about $fact
end

" ID过滤器"是在规则生成时确定的常量的集合。由于其他系统已经使用了Drools KB并且需要我的其他一些规则,因此将所有过滤器作为规则提供也是很自然和干净的。

然而,到目前为止,我还没有找到任何在DRL中声明此类常量集合的示例。请考虑以下限制因素:

  1. 因为常量是由规则生成器决定的,所以我不能要求客户端为这些常量插入全局事实。
  2. 过滤器可能是巨大的集合,每个集合可能包含10,000个ID,以及100个组合。使用规则将它们作为RHS中的事实插入的技巧将阻止我们使用StatelessKnowledgeSession。但是,使用StatefulKnowledgeSession也是不可能的,因为我们需要在高度并发的环境中执行规则。我们必须创建许多StatefulKnowledgeSessions,并且这些集合将使用大量内存在它们之间重复。
  3. 理想情况下,这些文件管理器在规则定义中被声明为常量,并以KB本身保存,因此客户端可以简单地使用StatelessKnowledgeSession

    Drools专家可以向我解释这是否可行?

    非常感谢。

1 个答案:

答案 0 :(得分:1)

规则可以用正确的DRL语法编写为

rule "X" // no colon here
when
  $fact: ToBeFilteredObject(id in (1, 2, 3, 4, 5) )
then
  // do something about $fact
end

请注意,即使只有getter是公共的,也可以通过其字段名称引用属性id

智能生成器当然会以一种方式处理过滤器集合,以减少由此产生的开销,如果所有元素都产生单个带括号的列表,那么(我猜)这将是相当大的。例如,集合(1,2,3,4,5,6, 11,12,13,14, 21,23,25)可以由规则

表示
rule "X"
when
  $fact: ToBeFilteredObject(id >= 1 && <= 6 || >= 11 && <= 14 || in (21,23,25) )
then
  // do something about $fact
end

最后,一个小Java将为您提供一种表达任意复杂过滤器的强大方法。

class MyBitSet extends BitSet {
    MyBitSet( String bits ){
        super();
        // set bits according to the String value
    }
}

,规则变为

rule "X"
when
  ToBeFilteredObject($id:id,
            new MyBitSet("01111100000111100000010101").get($id) )
then
  // do something about $fact
end

如果你真的有很多过滤器包含&#34;数十万&#34;基于对这些过滤器的全面分析,可能有更好的方法。

最后,您对有状态会话的假设是不正确的。在多个有状态会话之间共享规则库不会增加超出无状态会话所需的内存。插入的事实需要记忆。