如何在DRL文件的When子句中遍历字符串列表?附示例DRL代码
嘿,我注意到你在尝试在DRL的When子句里遍历字符串列表来匹配Person的Name属性,但这里得先给你提个醒:DRL的When区域是声明式的条件匹配模块,不能直接写add()、System.out.println()或者for循环这类命令式代码——这些操作都应该放到Then部分去执行。
下面给你几种正确实现需求的方法,你可以根据场景选择:
方法1:用memberOf直接匹配列表中的名字
这是最简洁的方式,利用Drools内置的memberOf操作符,判断Person的Name是否存在于目标列表中:
rule "AlertsCorrelation_5 : Do not group Disk Usage and Full GC together" when // 初始化要匹配的名字列表(也可以从工作内存的已有事实/全局变量中获取) $targetNames: List() from Arrays.asList("Test1", "Test2") // 收集所有符合条件的Person对象 $matchedAlertList: List() from collect( Person( Name memberOf $targetNames ) from $alertsRawList ) then // 这里处理匹配结果,比如打印列表 System.out.println("Matched alerts: " + $matchedAlertList); // 你的其他业务逻辑... end
如果你的名字列表是预先插入到工作内存的事实,直接引用变量即可,不用from Arrays.asList。
方法2:遍历列表逐个匹配(触发多次规则)
如果需要对列表中的每个名字单独匹配并处理,可以用嵌套模式遍历列表元素:
rule "Iterate Over Name List to Match Persons" when $targetNames: List() from Arrays.asList("Test1", "Test2") // 遍历列表中的每个名字 String($currentName: this) from $targetNames // 匹配对应Name的Person $matchedPerson: Person( Name == $currentName ) from $alertsRawList then // 每匹配到一个Person就触发一次规则,这里可以做单条数据的处理 System.out.println("Matched person for " + $currentName + ": " + $matchedPerson); end
这种方式会对每个匹配成功的Person单独触发规则,适合需要逐条处理的场景。
方法3:通过全局变量传入名字列表
如果名字列表是从外部Java代码传入的,可以定义全局变量来传递:
// 定义全局变量 global List<String> targetNameList; rule "Match Using Global Name List" when $matchedAlertList: List() from collect( Person( Name memberOf targetNameList ) from $alertsRawList ) then System.out.println("Matched from global list: " + $matchedAlertList); end
然后在Java代码中设置全局变量:
// 假设kSession是你的Drools会话对象 List<String> nameList = Arrays.asList("Test1", "Test2"); kSession.setGlobal("targetNameList", nameList);
纠正你原来的写法误区
你之前在When里写的$listOfNames.add("Test1");、System.out.println()都是错误的——When只能做条件判断,不能修改数据或执行命令式操作。如果需要在规则中创建列表,应该放到Then部分:
rule "Create List in Then Clause" when $alertsRawList: List() then List<String> listOfNames = new ArrayList<>(); listOfNames.add("Test1"); listOfNames.add("Test2"); System.out.println("listOfNames: " + listOfNames); // 如果需要用这个列表继续匹配,可以把它插入到工作内存 insert(listOfNames); end
总的来说,DRL的When要坚持声明式的匹配逻辑,用Drools提供的集合操作符(memberOf、collect、from等)来处理列表,命令式的代码全部放到Then中执行。
内容的提问来源于stack exchange,提问作者S.Surekha
相关产品推荐
相关产品推荐

