drools - 在drools中添加基于两个对象的规则条件
问题描述
> { "batch-execution":{
> "lookup":"defaultKieSession",
> "commands":[
> {
> "insert":{
> "out-identifier":"FieldData1",
> "object":{
> "FieldData":{
> "name":"abc",
> "value":"111"
> }
> }
> }
> },
> {
> "insert":{
> "out-identifier":"FieldData2",
> "object":{
> "FieldData":{
> "name":"xyz",
> "value":"222"
> }
> }
> }
> },
> {
> "fire-all-rules":{
>
> }
> }
> ] } }
现在我想在 drl 中写一个类似于这样的条件:
rule "testrule"
when
fieldData(name == "abc" , value == "111") && fieldData(name == "xyz",value = "222")
then
System.out.println("Condition executed")
有人可以帮助如何在流口水中做到这一点吗?
解决方案
Of course you can! Your "example" rule is nearly perfect as-is.
The way drool works is that it evaluates the conditions of all of the objects in working memory, and only if all conditions are met will it trigger that rule.
So you could write a rule that looks like this:
rule "Test Rule"
when
exists( FieldData( name == "abc", value == "111") )
exists( FieldData( name == "xyz", value == "222") )
then
System.out.println("Condition Executed")
end
This rule will trigger if there exists an object in working memory that has a name of 'abc' and a value of '111', and there also exists an object in working memory with the name of 'xyz' and value of '222'.
In the example above, I used the 'exists' predicate because we weren't going to actually be doing anything with those values, and we just wanted to confirm that there is such a FieldData object in memory that matches the required conditions.
Note that this assumes that you've entered your FieldData objects directly into the working memory as standalone objects. (Eg you fired the rules and passed it a List of FieldData.) If you're working with bigger structures, you'll have to extract the FieldData objects, and then do an exists check like I had in my previous example.
For example, let's say you had a set of classes like this (which mimic your example JSON; getters and setters omitted for brevity):
class FieldData {
String name;
String value;
}
class Command {
String outIdentified;
FieldData object;
}
class BatchExecution {
String action; // eg "insert"
String lookup;
List<Command> commands;
}
If you passed a BatchExecution
into the rules, you'll need to pull the field data out of the commands before you can check that two FieldData exist with the conditions you want. Your rule would therefore look more like this:
rule "Test Rule 2"
when
// Get the BatchExecution in working memory and pull out the Commands
BatchExecution( $commands: commands != null )
// Get the FieldData from each of the commands
$data: ArrayList( size >= 2) from
accumulate( Command( $fd: object != null ) from $commands,
init( ArrayList fieldDatas = new ArrayList() ),
action( fieldDatas.add( $fd ) ),
reverse( fieldDatas.remove( $fd ) ),
result( fieldDatas ))
// Confirm there exist FieldData with our criteria inside of the Commands
exists( FieldData( name == "abc", value == "111" ) from $data
exists( FieldData( name == "xyz", value == "222" ) from $data
then
System.out.println("Condition executed, 2");
end
Basically what we have to do is drill down from the object actually inserted into working memory until we can get to the objects that we need to be doing work against, in this case the FieldData. I used the accumulate
aggregate to pull all of the FieldData into a List that we then check for the presence of the two FieldData that we're looking for in this particular rule.
For more information, you should consider reading the Drools documentation, specifically the part on the "Rule Language Reference" (section 4) which is very well written and contains plenty of examples that you can adapt or expand upon.
推荐阅读
- azure-devops - 为什么“项目有效用户”组无权查看项目?
- java - Java 清单中的运行时版本信息
- powerapps-canvas - 如何在 Power Apps 的重复表中保存级联下拉值
- reactjs - 使用 reactjs 中的 firebase 中的新字段更新现有文档
- javascript - React 组件重新无限渲染
- html - 带左右角导航的全宽导航栏
- r - 尝试使用 pak 安装 pkgdown 开发版本时,在 GitHub 操作中安装 rlang 失败
- r - rjags 无法加载并且 R 无法找到任何版本的 JAGS
- r - 在 2 个字符串之间添加空格
- vba - VBA Web Scraping:当ie.visible = False时单击下载栏(保存文件)