返回Drools查询和组合查询的类型

时间:2018-03-02 14:48:44

标签: drools

我有一种情况需要检查是否有2个类型为A的EObject。为此,我编写了一个类似的查询:

query checkA()
$r1 : EObject(eClass().getName() ==  "A")
$r2 : EObject(eClass().getName() ==  "A",this != $r1)
end

以同样的方式,如果3个类型B的EObjects

query checkB()
$r1 : EObject(eClass().getName() ==  "B" , some_more_constraints)
$r2 : EObject(eClass().getName() ==  "B" , some_more_constraints,this != $r1)
$r3 : EObject(eClass().getName() ==  "B" , some_more_constraints,this != $r1,this != $r2)
end

我需要检查A类型的2个EObjects是 OR 类型B的3个EObjects。我有一个规则:

Rule "checking"
when
checkA()
||
checkB()
then
... do_something...

当我运行规则时,它会给出ClassCastException异常。

如果您能帮助我理解为什么会发生这种情况并回答以下两个问题,那将会非常有帮助。 a)我该如何实现? b)checkA()或checkB()查询的返回类型是什么?

如果我删除'||'来自规则的条件,然后它运行正常,没有任何错误。

非常感谢提前。

1 个答案:

答案 0 :(得分:1)

这里有两件重要的事情要理解:

  1. Drools中的查询在规则的when部分中使用时,不会返回值。
  2. ||运算符在Drools中不能作为通常的or运算符。
  3. 规则中的查询

    Drools中的查询(没有unbounds arguments)在规则的when部分内使用时,其行为类似于将其中的相同模式复制到规则中。

    我们以下面的DRL为例:

    query strings()
      $s1: String()
      String(this != $s1)
    end
    
    rule "Test"
    when
      strings()
    then
      //do something...
    end
    

    在会话中插入2 Stringss1s2)时,我们将对Test规则进行2次激活:

    • 激活1:[s1, s2]
    • 激活2:[s2, s1]
    模式之间

    OR

    当Drools找到||时在规则模式之间,它基本上将规则拆分为2.在任何其他编程语言中,此行为与常规or之间的最大区别在于or操作的两个部分如果是这样,规则将被激活两次。

    因此,例如,以下规则:

    rule "Test"
    when
      String(this == "ABC") ||
      String(this == "DEF")
    then
      //Do something
    end
    

    将在运行时创建2个不同的规则:

    rule "Test-1"
    when
      String(this == "ABC")
    then
      //Do something
    end
    
    rule "Test-2"
    when
      String(this == "DEF")
    then
      //Do something
    end
    

    使用||时的一个问题是,在模式中使用绑定变量时必须非常小心,因为您不知道它们是否包含值。

    我猜你的异常实际上是由你如何在规则的when部分绑定变量引起的

    我希望现在您对使用查询和||运算符时Drools的工作方式有了更多了解,您将能够找到异常发生的位置和原因。