我们正在开发一个监控应用程序,我们在其中跟踪一组应用程序中的任务处理。 每个应用程序任务处理都设计为ChainStep,整个任务流程设计为Chain。 Chain包含ChainSteps树,每个ChainStep可能是其他的父。 我们有一套符合我们需求的drools规则,但是我们遇到了一些性能问题(在会话中我们可能容易达到多达5万个对象)。 我们正在寻找改善流氓表现的最佳实践。
目前我们将Chains和ChainSteps表示为扁平对象,每个对象都有Id(GUID),我们经常有以下条件的规则:
rule "Chain_App1_LinkToParent"
when $app1Step:App1ChainStep(!HasParent )
$app2Step:App2ChainStep($app2Step.ChainId == $app1Step.ChainId)
then
modify($app1Step) {
setParent($app2Step.getId()),
setHasParent(true)
}
end
(App1ChainStep和App2ChainStep都扩展了ChainStep类型)
我们尝试使用统一,但规则处理似乎较慢
when $app1Step:App1ChainStep(!HasParent, $Id:=ChainId )
$app2Step:App2ChainStep($Id:=ChainId)
我们现在正在使用非平面表示,但是我们在触发对象修改的规则上遇到问题。 例如:
rule "SetChainCollectable"
when
$chain:Chain(!Collectable )
not ( exists( $chainStep:ChainStep( !Collectable) from $chain.Steps))
then
modify($chain){
setCollectable(true)
}
end
似乎没有在ChainStep修改Collectable标志时触发。
我们希望在芬兰之前获得更好的结果来移植我们的规则。
在Drools中表示对象树的更有效方法是什么?
答案 0 :(得分:0)
为了设计有效的事实表示,必须考虑所有用例及其频率。 (你在问题中发表的内容远非如此。)所以我只能指出我观察到的一些奇怪之处:</ p>
parent
和hasParent
的维护。大多数情况下,ID具有空值NULL
或0
等。也许您应该引用引用而不是ID值。not( exists() )
是多余的 - not()
本身就是负存在量词。 (在这种情况下,Drools会丢弃exists
。)from <expression>
迭代集合中的一些POJO(不是事实)会创建我称之为&#34;临时事实&#34;,作为事实,它们仅限于from子句的条件的上下文是写的。因此,引擎不知道ChainStep
对象的任何修改。如果您希望规则对其修改作出反应,ChainStep对象必须是事实。基本上,将节点表示为事实并将参考表示为邻居 - 向上或向下,或向上和向下,甚至包括兄弟姐妹(如果它是树) - 是要走的路。但我不想多说 - 见最初段落。