Drools中使用EXISTS关键字获取WHEN段值且避免笛卡尔积的问题
问题根因
- 初始规则报
$threat无法解析错误:Drools 中exists关键字仅用于判断符合条件的事实是否存在,不会将其绑定的变量传递到规则后续上下文(包括THEN执行段),因此THEN段无法引用exists绑定的变量。 - 调整后出现笛卡尔积:你保留了冗余的
exists $threat判断行,同时保留了冗余的exists AttackVector判断,多组重复的匹配逻辑交叉命中,导致同一组符合条件的事实被多次触发,插入重复的RiskRating对象。
优化后规则
rule "attaching AV and impact rating" agenda-group "evaluate likelihood" dialect "java" when Application($threatList : getThreatList()) // 直接绑定符合条件的AttackVector,合并原有的exists判断条件 $av:AttackVector(this == AttackVector.REQUEST_MANIPULATION) // 直接绑定符合条件的Threat实例,删除冗余的exists判断 $threat:Application.Threats(impact == "Disclose Information") from $threatList then RiskRating riskRating = new RiskRating($threat.getImpactRating(), $av.getLikelihood(), $av.getName()); insertLogical(riskRating); end
方案说明
- 所有需要在THEN段引用的变量都通过非
exists的匹配逻辑直接绑定,不会出现变量无法解析的问题。 - 删掉了所有冗余的匹配条件,不会产生交叉匹配的笛卡尔积,每一组符合条件的
$av和$threat只会触发一次规则执行。 - 配合你使用的
insertLogical逻辑插入能力,只要规则匹配条件持续成立,完全相同的RiskRating实例不会被重复插入工作内存。
内容的提问来源于stack exchange,提问作者JAMSHAID
相关产品推荐
相关产品推荐

