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

如何修改Drools规则以支持personLastDatas为空时触发?

这个问题我之前也碰到过——核心原因是Drools的accumulate函数在没有匹配的源数据时,不会绑定目标变量。也就是说当$person.personLastDatas为空集合时,$maxLastDate那一行的条件根本不会匹配,规则的条件链在这里就断了,自然不会进入后续的($maxLastDate == null || ...)判断。

给你两种可行的解决方案,按需选择:

方案1:拆分条件,明确处理空集合场景

这种写法逻辑直观,把“空集合”和“有数据但日期过期”拆成两个并列分支,用or连接:

rule "Insert a too old condition modified" salience -1
when
    $person : Person()
    $tooOldInstant : DateTime() from now.minusDays(10)
    (
        // 分支1:personLastDatas是空集合
        not exists(LastData() from $person.personLastDatas)
        or
        // 分支2:存在数据,且最新的lastDate早于阈值
        DateTime( this < $tooOldInstant ) from accumulate ( 
            LastData( $date : lastDate ) from $person.personLastDatas, 
            maxValue($date) 
        )
    )
then
    insert(new Condition("submitTooOldCondition"));
end

方案2:自定义Accumulate逻辑,让空集合返回null

如果你更倾向于用单个Accumulate处理两种情况,可以通过init/action/result语法自定义累加逻辑,确保空集合时返回null:

rule "Insert a too old condition modified" salience -1
when
    $person : Person()
    $tooOldInstant : DateTime() from now.minusDays(10)
    $maxLastDate : Object() from accumulate ( 
        LastData( $date : lastDate ) from $person.personLastDatas,
        init( DateTime maxDate = null; ),
        action( 
            // 更新最大值:如果当前max为null,或者新日期更晚就替换
            if (maxDate == null || $date.isAfter(maxDate)) {
                maxDate = $date;
            }
        ),
        result( maxDate ) // 空集合时返回null
    )
    // 空集合时$maxLastDate为null,直接判断即可;非空时校验日期
    ($maxLastDate == null || ($maxLastDate instanceof DateTime && ((DateTime)$maxLastDate).isBefore($tooOldInstant)))
then
    insert(new Condition("submitTooOldCondition"));
end

这里要注意把$maxLastDate的类型声明为Object(),因为空集合时返回的是null,Drools无法自动推断为DateTime类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:22:48