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 在他的回答中所展示的那样。
但是,如果您只想验证列表中是否包含符合您标准的对象,那么积累就太过分了,这就是合适的解决方案。
我想创建我的规则更通用的格式,这意味着它应该验证字段和值。按照我的 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 中进行验证?
提前致谢。
你可以
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 在他的回答中所展示的那样。
但是,如果您只想验证列表中是否包含符合您标准的对象,那么积累就太过分了,这就是合适的解决方案。