You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drools:如何在not表达式内实现短路与(&&)条件?

在Drools的not表达式中实现短路与逻辑

我懂你的困扰——在not表达式里,Drools引擎没按你预期的短路逻辑执行,导致非double类型的数据也调用了getValue()方法,最后因为类型不匹配报错。这是因为Drools处理模式约束时,会做内部优化,不一定严格按照你写的顺序执行,所以哪怕name不匹配,getValue()还是可能被提前调用。

要解决这个问题,我们可以通过拆分模式的方式,强制先过滤出符合name条件的实例,再对这些实例做getValue()和时间条件的判断,以此实现类似短路与的效果。

修改后的规则代码

rule "data value > 50 for 10 seconds"
dialect "java"
when
    // 先匹配double类型且value>50的数据
    data: MyData(name.contains("double"), getValue() > 50) from entry-point "dataEntryPoint"
    // 在not中拆分逻辑,先筛选同name的实例,再判断后续条件
    not(
        // 第一步:仅保留和当前data同name的记录,完全不涉及getValue()
        $candidate: MyData(name == data.name) from entry-point "dataEntryPoint"
        // 第二步:只对筛选后的实例,判断value<50且在时间范围内
        MyData(
            this == $candidate,
            getValue() < 50,
            this after[0, 10s] data
        )
    )
then
    doSmthg();
end

为什么这样能解决问题?

  1. 第一个子模式$candidate: MyData(name == data.name)会先从入口点筛选出所有name匹配的MyData实例,这一步完全不会调用getValue()。
  2. 只有通过第一步筛选的实例,才会进入第二个子模式执行后续判断,彻底避免了非double类型的数据触发getValue()方法。

更简洁的替代写法

如果你追求代码简洁,也可以在not的模式中把name约束放在最前面,利用Drools的约束优先级(字段约束优先于方法调用约束)来实现短路效果:

rule "data value > 50 for 10 seconds"
dialect "java"
when
    data: MyData(name.contains("double"), getValue() > 50) from entry-point "dataEntryPoint"
    not(
        MyData(
            name == data.name, // 字段约束优先执行
            getValue() < 50, // 只有name匹配才会执行这个方法调用
            this after[0, 10s] data
        ) from entry-point "dataEntryPoint"
    )
then
    doSmthg();
end

这种写法的核心是Drools会优先处理字段匹配类的约束,再处理方法调用类的约束,也能达到短路效果,但拆分模式的写法更直观,可读性更强,也不容易因为引擎优化出现意外。

内容的提问来源于stack exchange,提问作者bjalexmdd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:02:35