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

如何在Drools中使用exists判断元素存在并引用该元素?

Drools中结合exists使用变量并避免多次匹配的解决方案

核心问题分析

Drools的exists关键字仅用于判断对象是否存在,不会将其内部子模式中绑定的变量暴露到规则的动作(then)块中,这就是你第一种写法报错$id cannot be resolved to a variable的原因。而第二种写法因为先单独匹配了所有符合条件的对象,再用exists做存在性检查,导致每个匹配对象都会触发一次规则,所以执行多次。

正确实现方式

要同时实现存在性检查(避免多次触发)和获取匹配对象的引用,需要将变量绑定放在exists包裹的完整模式内部。结合你的Rule Unit和POJO结构,正确的规则写法如下:

写法1:绑定匹配的City对象

package test;
unit TestUnit;

rule "test_rule"
when
    // 检查存在至少一个TestRule,其cityList中包含name为Washington的City,并绑定该City对象
    exists TestRule( $targetCity: cityList[ name == "Washington" ] )
then
    System.out.println("匹配到的City ID: " + $targetCity.getId());
end

写法2:直接绑定City的id属性

package test;
unit TestUnit;

rule "test_rule"
when
    // 检查存在至少一个TestRule,其cityList中包含name为Washington的City,并绑定该City的id
    exists TestRule( cityList[ $id: id, name == "Washington" ] )
then
    System.out.println("匹配到的City ID: " + $id);
end

为什么这个写法有效

  • exists关键字确保规则仅在Working Memory中存在至少一个符合条件的TestRule(其cityList包含目标City)时触发一次,避免了多次匹配的问题
  • 变量($targetCity或$id)绑定在exists包裹的TestRule模式内部,会被暴露到规则上下文,因此可以在then块中直接使用

额外说明

如果你的需求是:只要存在符合条件的City,就获取第一个匹配的对象并执行一次动作,上述写法完全满足。如果需要处理所有匹配的对象但只执行一次动作,可以结合collect关键字,但这种场景下exists的存在性检查已经足够。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:26:11