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

Java 如何在Drools 5.6规则中定义常量集合,java,drools,Java,Drools,我用的是Drools 5.6。我需要将规则/知识库传递到另一个系统。我的一些规则是一种ID过滤器。例如,以非法语法表示,它看起来像: rule "X": when $fact: ToBeFilteredObject(this.getId() in [1, 2, 3, 4, 5, ...]) then // do something about $fact end “ID筛选器”是规则生成时确定的常量集合。因为另一个系统已经使用了Drools KB,并且需要我提供一些其他

我用的是Drools 5.6。我需要将规则/知识库传递到另一个系统。我的一些规则是一种ID过滤器。例如,以非法语法表示,它看起来像:

rule "X":
  when
    $fact: ToBeFilteredObject(this.getId() in [1, 2, 3, 4, 5, ...])
  then
    // do something about $fact
end
“ID筛选器”是规则生成时确定的常量集合。因为另一个系统已经使用了Drools KB,并且需要我提供一些其他规则,所以我也可以将所有过滤器作为规则交付,这将是自然和干净的

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

  • 因为常量是由规则生成器确定的,所以我不能要求客户端为这些常量插入全局事实
  • 这些过滤器可能是一个巨大的集合,每个集合可能包含10000个ID,加起来可能是1000个ID中的100个。使用规则将它们作为事实插入RHS的技巧将阻止我们使用
    无状态知识会话
    。但是,使用
    StatefulKnowledgeSession
    也是不可能的,因为我们需要在高度并发的环境中执行规则。我们必须创建许多
    StatefulKnowledgeSessions
    ,这些集合将在它们之间复制,使用大量内存 理想情况下,这样的文件管理器在规则定义本身中声明为常量,并保存在KB中,这样客户机就可以简单地使用
    无状态KnowledgeSession

    这里的Drools专家能解释一下这是否可行吗


    非常感谢

    规则可以用正确的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
    
    规则变成了

    rule "X"
    when
      ToBeFilteredObject($id:id,
                new MyBitSet("01111100000111100000010101").get($id) )
    then
      // do something about $fact
    end
    
    如果您确实有很多包含“数十万”值的过滤器,那么基于对这些过滤器的彻底分析,可能有更好的方法


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

    谢谢您的回答。显然,你的例子是有效的。我重新查阅了Drools文档。它实际上为“in”操作符提供了这样一个示例。我真傻。
    rule "X"
    when
      ToBeFilteredObject($id:id,
                new MyBitSet("01111100000111100000010101").get($id) )
    then
      // do something about $fact
    end