Java Drools Core DRL-只触发一条显著性最高的规则,跳过其他规则

Java Drools Core DRL-只触发一条显著性最高的规则,跳过其他规则,java,drools,rule,Java,Drools,Rule,我有一个简单的javabean,它有两个int字段:“a”和“b” 我有两条规则: rule "First rule" salience 10 when $bean : Bean ( a == 1) then $bean.setB(10); end rule "Second rule" salience 20 when $bean : Bean ( a == 1) then $bean.setB(20); end 实际结果:“第二条规则”首先触发(更高的显著性

我有一个简单的javabean,它有两个int字段:“a”和“b”

我有两条规则:

rule "First rule"
salience 10
when
    $bean : Bean ( a == 1)
then
    $bean.setB(10);
end

rule "Second rule"
salience 20
when
    $bean : Bean ( a == 1)
then
    $bean.setB(20);
end
实际结果:“第二条规则”首先触发(更高的显著性),“第一条规则”第二次触发

预期结果:仅触发一条规则(具有最高显著性)。其他规则被忽略。如何做到这一点?流口水有可能吗?我正在使用Drools 6.0.0决赛

要求: 1.我不能使用“激活组”。 2.我不想在每个bean上使用“retract”

更新

非常感谢你的回答

也许我应该详细描述我的问题。 我有一套1500条规则。每项规则:

  • 使用同一个bean-这个bean有很多字段(属性)
  • 具有显著性
  • 有很多条件,
  • 只有一个操作-在我的bean中设置一个(总是相同的)布尔标志
我想要什么? 当我有冲突时(输入事实由两个或多个规则匹配),我只想触发一个具有最高显著性的规则。应忽略这一事实的其他匹配规则。最重要的是性能-这应该尽可能快地工作

我做什么? 目前我有两个解决方案,但我不知道哪一个更好,或者我应该用不同的方式解决这个问题

解决方案1-状态完整会话

Java代码:

for (Object fact : facts) {
    FactHandle fh = session.insert(fact);
    session.fireAllRules(1);
    session.delete(fh);
}
for (Object fact : facts) {
    session.execute(fact);
}
解决方案2-无状态会话

Java代码:

for (Object fact : facts) {
    FactHandle fh = session.insert(fact);
    session.fireAllRules(1);
    session.delete(fh);
}
for (Object fact : facts) {
    session.execute(fact);
}
解决方案2的DRL文件: 我向每个规则添加了相同的激活组:

rule "Rule"
activation-group "group"
salience X
when
    ...
then
    ...

首先,让我告诉你,这里有一些奇怪的场景:)

此问题有多种解决方案:

  • 使用Bean类的另一个属性来标记已经“处理”的事实
  • 使用自定义代理过滤器
  • 使用ksession.fireAllRules(1)

希望能有所帮助,

基于你的问题,我担心你可能误解了显著性的意义。显著性是一种优先级值。Drools使用它来确定在满足多个规则的约束时首先触发哪个drool

[在某些情况下触发规则p而不是触发规则p时触发规则Q]的问题是一个常见的问题。对象模型的设置应确保这是对概念空间进行推理的自然结果。对于您列出的文字情况,您可以尝试在工作内存中插入一个新事实(“RuleFiredFact”,值为“2nd”或其他)。然后在第一个规则约束中检查这一事实。如果这是真的,第一条规则不会触发

更新: 要清楚,“RuleFiredFact”是事实模型中某些具体事实的抽象占位符。drools的一部分要点是在drools DSL中不使用抽象的东西

更新:

有状态会话与无状态会话是否合适,将在很大程度上取决于您可用的计算机资源、对象模型、团队,列表还有很多。如果你不知道该用哪一个,你应该参考关于这个主题的讨论。你可以试试这个旧邮件列表

无论你选择哪一种,我强烈怀疑你的对象模型太浅了。创建一个包含一个事实的drools系统,然后再也不会创建任何事实,这是非常罕见的。垂涎三尺的目的是对一些事实进行推理。解决这个问题的方法可能是通过移动对象并将其中的信息作为事实插入drools工作记忆。然后,您将编写只在您想要的约束下触发的规则


在我描述的情况下,有很多方法可以确保只触发一条规则。您的规则可能都在寻找一个“factWasAlreadyReasonedOverFact”,其中引用了触发执行的事实。这是一个相当粗略的例子。希望它能给你一个想法。

我会使用
激活组
显著性
来解决这个问题,正如你在解决方案2中所描述的那样。

你可以尝试的一个解决方案是“锁定活动”属性,以避免涉及一个或多个规则的无限执行循环

激活锁定由规则组确定范围,只要该组处于焦点状态,就会防止规则重新触发。它不取决于新的事实或对现有事实的更新,而只取决于议程重点。如果您不操纵组,这可能是一个选项。

您可以使用drools.halt();在你的最高显著性规则中

这样做的目的是终止流程并退出规则执行(这正是您所需要的)