首页 > 解决方案 > 在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")

有人可以帮助如何在流口水中做到这一点吗?

标签: droolsrule-engine

解决方案


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.


推荐阅读