如何在drools中编写嵌套条件

gau*_*620 7 drools

这是我的JSON文档

    {
   "location": {
      "details": [
         {
            "country": "India",
            "state": "haryana"
         },
         {
            "country": "America",
            "state": "LA"
         },
         {
            "country": "India",
            "state": "Maharashtra"
         }
      ]
   },
   "organisation": {
      "details": [
         {
            "name": "AON",
            "country": "india"
         },
         {
            "name": "AON",
            "country": "America"
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)

我必须以下面的格式应用规则

 If(

        (location.details.country=='India' OR 
        location.details.state=='haryana') 
AND 

        organisation.details.name=='AON'
    )
Run Code Online (Sandbox Code Playgroud)

直到现在我已经研究并知道同一类字段的规则可以用嵌套格式应用,如下所示.在这个链接:如何在drools中写入嵌套条件

// Use this instead
Person( ( age > 50 && weight > 80 ) || height > 2 )
Run Code Online (Sandbox Code Playgroud)

但我想在相同的嵌套条件下应用不同pojo类的规则,如下所示

    If(

                (location.details.country=='India' OR 
                location.details.state=='haryana') 
        AND 

                organisation.details.name=='AON'
      AND 
               (location.details.country=='India' AND
                organisation.details.country=='India')
            )
//any level of nested between different pojo classes can be present
Run Code Online (Sandbox Code Playgroud)

这可能是流口水吗?

我写了以下规则

rule "rule1"
salience 1
when


        $rootDoc:RootDoc($locationList:location && $organisationList:organisation) 

     and
        (
            $orgList:Organisation($orgdetailsList:details) from $organisationList
            NamesList1:Details(name=='AON') from $orgdetailsList
            or
            $locList:Location($locdetailsList:details) from $locationList
            NamesList2:Details_(state=='haryana') from $locdetailsList

        )

then
    System.out.println("Pojo Welocome-------");



end
Run Code Online (Sandbox Code Playgroud)

但它显示我这个错误:第18:3行规则"rule1"中的输入'NamesList1'不匹配

基本上当我在同一个括号中写两个条件时,它会显示错误.

以下是pojo类

-----------------------------------pojo_Classes2.Detail.java-----------------------------------

package pojo_Classes2;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"name",
"country"
})
public class Detail {

@JsonProperty("name")
private String name;
@JsonProperty("country")
private String country;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("name")
public String getName() {
return name;
}

@JsonProperty("name")
public void setName(String name) {
this.name = name;
}

@JsonProperty("country")
public String getCountry() {
return country;
}

@JsonProperty("country")
public void setCountry(String country) {
this.country = country;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}
-----------------------------------pojo_Classes2.Detail_.java-----------------------------------

package pojo_Classes2;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"country",
"state"
})
public class Detail_ {

@JsonProperty("country")
private String country;
@JsonProperty("state")
private String state;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("country")
public String getCountry() {
return country;
}

@JsonProperty("country")
public void setCountry(String country) {
this.country = country;
}

@JsonProperty("state")
public String getState() {
return state;
}

@JsonProperty("state")
public void setState(String state) {
this.state = state;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}
-----------------------------------pojo_Classes2.Location.java-----------------------------------

package pojo_Classes2;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"details"
})
public class Location {

@JsonProperty("details")
private List<Detail_> details = null;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("details")
public List<Detail_> getDetails() {
return details;
}

@JsonProperty("details")
public void setDetails(List<Detail_> details) {
this.details = details;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}
-----------------------------------pojo_Classes2.Organisation.java-----------------------------------

package pojo_Classes2;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"details"
})
public class Organisation {

@JsonProperty("details")
private List<Detail> details = null;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("details")
public List<Detail> getDetails() {
return details;
}

@JsonProperty("details")
public void setDetails(List<Detail> details) {
this.details = details;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}
-----------------------------------pojo_Classes2.RootDoc.java-----------------------------------

package pojo_Classes2;

import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"organisation",
"location"
})
public class RootDoc {

@JsonProperty("organisation")
private Organisation organisation;
@JsonProperty("location")
private Location location;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("organisation")
public Organisation getOrganisation() {
return organisation;
}

@JsonProperty("organisation")
public void setOrganisation(Organisation organisation) {
this.organisation = organisation;
}

@JsonProperty("location")
public Location getLocation() {
return location;
}

@JsonProperty("location")
public void setLocation(Location location) {
this.location = location;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}
Run Code Online (Sandbox Code Playgroud)

我想我已经找到了问题.

这样对吗?

发生这种情况是因为如果条件为OR,则无法绑定变量并在RHS中使用它.

Rod*_*eas 4

是的,这是完全可能的。

为简单起见,我假设您放入工作内存的对象的结构如下:

class Data {
  Location location;
  Organization organization;
}
Run Code Online (Sandbox Code Playgroud)

子类定义如下:

class Location {
  List<Detail> details;
}
class Organization {
  List<Detail> details;
}
class Detail {
  String name;
  String country;
  String state;
}
Run Code Online (Sandbox Code Playgroud)

这应该可以准确地对您的问题中的 JSON 进行建模。为了简洁起见,省略了这些类中的 getter 和 setter。

现在,我们的目标是编写一条规则,当存在同时具有国家=“印度”和州=“哈里亚纳邦”的Detail内部时触发;Location也存在一个名称为“AON”的Detail内部。Organization

我们可以按如下方式完成此操作:

rule "Trigger when Haryana, India is a Location and AON is an Organization name"
when
  // First we need to extract the location and organization so we can do work on them
  Data( $location: location != null,
        $organization: organization != null )

  // Confirm that there exists an organization detail with name = "AON"
  Organization( $orgDetails: details != null ) from $organization
  exists( Detail( name == "AON" ) from $orgDetails )

  // Confirm that there exists a location with country = India and state = Haryana
  Location( $locDetails: details != null ) from $location
  exists( Detail( country == "India", state == "Haryana" ) from $locDetails )
then
  System.out.println("Rule has been executed")
end
Run Code Online (Sandbox Code Playgroud)

我使用exists谓词是因为我只是检查这些满足条件的对象是否存在。如果我们想将识别的对象绑定到变​​量,您可以简单地进行赋值——例如:

// This snippet matches the previous rule where we identify an Organization detail with name of "AON"
Organization( $ordDetails: details != null ) from $organization
$aon: Detail( name == "AON" ) from $orgDetails
Run Code Online (Sandbox Code Playgroud)

或者甚至自己分配属性:

// This snippet matches the previous rule where we identify the Location detail for Haryana, India
Location( $locDetails: details != null ) from $location
Detail( country == "India",
        state == "Haryana",
        $name: name ) from $locDetails
Run Code Online (Sandbox Code Playgroud)

我对 Jackson 的绑定库不是很熟悉,但根据我对您发布的 POJO 的理解,对于您直接使用的对象,语法即使不相同,也应该非常相似。(据我所知,你的“RootDoc”和我的“数据”实际上是同一件事。)

无论如何,这是有效的,因为 Drools 会评估所有左侧条件,以便决定是否应触发规则。因此,如果我们查看示例规则,它会检查组织内部是否存在满足我们条件的详细信息(名称为“AON”)。如果不满足此条件,则不会触发规则,因为左侧此时已评估为“假”。如果确实存在,我们就会检查 Location 内是否有符合我们条件的详细信息(国家/地区 = 印度,州 = 哈里亚纳邦)。仅当满足左侧所有条件时才会触发此规则;它是一组“自然”ed条件。

我认为值得指出的是,必须在同一谓词内检查“国家=印度”和“州=哈里亚纳邦”。否则,最终可能会出现这样的情况:您有两个详细信息,每个详细信息都有一半的条件,但没有一个详细信息同时具有这两个条件。例如,您可能有一个“国家/地区”为空但州为哈里亚纳邦的详细信息,以及一个“国家/地区”为印度且州为马哈拉施特拉邦的详细信息;如果您没有在同一谓词中进行两项检查,则即使您没有满足这两个条件的详细信息,这种情况也可能会触发该规则。