我仍然试图围绕一些流氓的基础知识。 我不明白的一件事是,我必须明确地将事实添加到会话中,而不是将事物声明为事实或(如何区别?)作为规则中的变量。
问题:我是否总是必须明确地添加一个事实,或者是否也将某个声明的变量视为一个事实?
说我有这个简化的层次结构:
public class Container {
private Collection<Element> elements;
// other stuff
}
public class Element {
private SubElement subElement;
// other stuff
}
public class SubElement {
private code;
// other stuff
}
现在我想查找/匹配包含具有给定代码的SubElement的Elements的容器。 这是我创建的规则:
global Collection qualifyingCodes;
rule "container rule"
when
// find a container
$container : Container( $elements : elements )
// where there is an element within its elements list
$element : Element(this memberOf $elements)
// that has a sub element
$subElement : SubElement(this == $element.subElement)
// for which the code is in the (global) list of codes
eval(qualifyingCodes.contains($subElement.code))
then
....
现在它似乎运行正常,但只有当我将容器,元素和子元素作为事实分别添加到我的会话中时。 我希望能够将容器对象添加为事实并由于&#34;声明&#34; $ elements / $ element / $ subElement drools也将这些理解为事实。 有没有办法做到这一点(或者我是否总是要扁平化我的数据结构并将其作为单独的事实添加)?
感谢您的任何建议!
答案 0 :(得分:1)
作为事实插入的POJO可以与模式匹配,而无需建立上下文(正如您的规则所说明的那样)。
然而,可以创建一个上下文,其中可以或可能未作为事实插入的有限POJO集可以通过模式匹配:通过from
短语。这里基本上是相同的规则,但没有Element和SubElement是事实:
rule "from rule"
when
// find a container
$container : Container( $elements : elements )
// where there is an element within its elements list
$element : Element($subEl: subElement ) from $elements
// that has a sub element
$subElement : SubElement(this == $element.subElement, data == "DEF")
from $subEl;
then
System.out.println( "found Container " + $container +
" for " + $subElement.getData());
end
但是,除了在一般情况下可见之外,插入作为一个事实也有另一个结果:事实可以通过引擎知道该修改来修改。在“from rule”中,无法修改$ subElement,因此将SubElement的数据设置为“DEF”的任何修改都不会触发此规则(即使插入SubElement POJO也不会)。
为了完整起见:通过添加对父对象的引用,也简化了对象层次结构(组合)的推理,例如
rule "linkage rule"
when
// a sub element GHI
$subElement : SubElement( data == "GHI", $element: element)
then
System.out.println( "found Container " + $element.getContainer() +
" for " + $subElement.getData());
end