Java - 通用 Drools 规则

Java - Generic Drools rule

我想创建我的规则更通用的格式,这意味着它应该验证字段和值。按照我的 POJO 结构。

 public class RulesModel
private String field;
private List<String> values;
// other stuff  

还有我的规则

rule "sample"
when
    $rule : RulesModel( field == "source", values contains "facebook", values contains "youtube", value not contains "instagram" )  
then
    // actions
end  

验证单个字段工作正常,但我想验证 RulesModel 的多个字段。 所以我想创建 POJO

public class RulesModelList {

    private List<RulesModel> ruleList;
    // Getter & Setter
}

所以现在当我使用 RulesModelList class 传递 RulesModel 列表时,规则应该像下面这样验证

$rule : RulesModel( field == "source", values contains "facebook") && $rule : RulesModel( field == "createdBy", values contains "admin")

如何在 Drools 中进行验证?

提前致谢。

你可以 in when block, for example CollectionUtils.intersection

import static org.apache.commons.collections4.CollectionUtils.intersection;
...
$rule : RulesModel( field == "source", !intersection(values, valuesToCheck).isEmpty())

您可以使用

分析元素集合
RulesModelList($ruleList: ruleList)
$matchingList: List() from accumulate (
    $model: RulesModel(field == "source", values contains "facebook", values contains "youtube", value not contains "instagram") from $ruleList,
    accumulateList($model)
)

如果您要做的只是验证列表中是否有这两个(或三个或更多)RulesModel,这非常简单:

// Example from question
rule "Verify Facebook source and admin createdBy"
when
  RulesModelList( $list: ruleList)
  exists(RulesModel( field == "source", values contains "facebook") from $list)
  exists(RulesModel( field == "createdBy", values contains "admin") from $list)
then
  // do something
end

基本上我从 RulesModelList 输入中获取 RulesModel 列表并分配给 $list。然后我验证是否存在一个符合我的 'source' 标准的 RulesModel 实例,然后是一个符合 'createdBy' 标准的实例。

在示例中,我使用 exists() 而不是分配变量,因为我的示例规则不需要使用右侧的 RulesModel 实例。如果您 do 需要对 RulesModel 实例做一些事情,只需将 exists() 替换为这样的赋值:

$source: RulesModel( field == "source", values contains "facebook") from $list
$createdBy: RulesModel( field == "createdBy", values contains "admin") from $list

除非您尝试遍历列表并找到符合特定条件的内容,否则无需进行累加。例如,假设 "field" 值之一是 "updatedBy",并且可以有多个具有该字段名称的 RulesModel 实例。要获取字段名称为 "updatedBy" 的 RulesModel 实例的子集,您需要使用 accumulate,正如 Mykhaylo 在他的回答中所展示的那样。

但是,如果您只想验证列表中是否包含符合您标准的对象,那么积累就太过分了,这就是合适的解决方案。