2015-11-03 333 views
3

我的规则文件,比较日期在Drools中,如下

import com.springapp.mvc.model.Person; 
dialect "java" 
rule "4" 
    when 
     $person:Person(((date > "20-Jan-2015") && (date < "20-Dec-2015")) && (call_count >= "299")) 
    then 
     System.out.println("Beep"); 
end 

我加了下面的人对象,如下消防规则,

Person person = new Person(); 
person.date = "20-Feb-2015"; 
person.call_count = 400; 
kSession.insert(person); 
int fires = kSession.fireAllRules(); 

但它并没有打印出“哔”。我认为条件不匹配,但我不明白为什么会发生这种情况。我如何比较口水中的日期?

我的实际规则集,

package Customer_Loyalty_Categorization; 
import com.springapp.mvc.model.Person; 
dialect "java" 

rule "4" 
    when 
     $person:Person(((date > "10-Nov-2015") && (date < "10-Dec-2015")) && (call_count >= "299")) 
     $person:Person(((date > "10-Nov-2015")&&(date < "30-Dec-2015")) && (call_count >= "299")) 
    then 
     System.out.println("Point rule runs."); 
     $person.points = ($person.call_count)*0.2; 
end 

rule "6" 
    when 
     $person:Person(call_count >= "599") 
    then 
     System.out.println("Category rule runs."); 
     $person.setCategory('PLATINUM'); 
end 

并改变人的日期变量的类型后,我得到了以下异常,

java.lang.RuntimeException: Unable to Analyse Expression date > "20-Nov-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date > "20-Nov-2015" ....}] 
        ^
[Line: 8, Column: 8] : [Rule name='4'] 

Unable to Analyse Expression date < "20-Dec-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date < "20-Dec-2015" ....}] 
        ^
[Line: 8, Column: 8] : [Rule name='4'] 

Unable to Analyse Expression date > "01-Jan-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date > "01-Jan-2015" ....}] 
        ^
[Line: 40, Column: 8] : [Rule name='1'] 

Unable to Analyse Expression date < "07-Jan-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date < "07-Jan-2015" ....}] 
        ^
[Line: 40, Column: 8] : [Rule name='1'] 

Unable to Analyse Expression date > "01-Jan-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date > "01-Jan-2015" ....}] 
        ^
[Line: 48, Column: 8] : [Rule name='2'] 

Unable to Analyse Expression date < "07-Jan-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date < "07-Jan-2015" ....}] 
        ^
[Line: 48, Column: 8] : [Rule name='2'] 

Unable to Analyse Expression date > "05-Jan-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date > "05-Jan-2015" ....}] 
        ^
[Line: 48, Column: 8] : [Rule name='2'] 

Unable to Analyse Expression date < "10-Jan-2015": 
[Error: Comparison operation requires compatible types. Found class java.util.Date and class java.lang.String] 
[Near : {... date < "10-Jan-2015" ....}] 
        ^
[Line: 48, Column: 8] : [Rule name='2'] 

我生成规则的字符串设定和转换他们使用以下功能进入知识库,

public void createKnowledgeBase(){ 
     String ruleSet = loadRuleSet();//generate rules as strings. 
     try { 
      System.out.println(ruleSet); 
      long start = System.currentTimeMillis(); 
      if(ruleSet!=null){ 
       KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
       Resource myResource = ResourceFactory.newReaderResource(new StringReader(ruleSet)); 
       knowledgeBuilder.add(myResource, ResourceType.DRL); 
       if (knowledgeBuilder.hasErrors()) { 
        throw new RuntimeException(knowledgeBuilder.getErrors().toString()); 
       } 
       knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase(); 
       knowledgeBase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages()); 
      } 
      long finish = System.currentTimeMillis(); 
      System.out.println("Execution time = " + (finish-start) + " milliseconds."); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
+0

我正在使用Drools 6.3.0。如果我删除日期比较部分这个规则工作正常。 – Hasitha

+0

查看我的答案... – laune

+0

啊,最后 - 缺少的信息已经到达。看到我的答案还有一个补充。 – laune

回答

2

显然,你有

class Person { 
    String date; 
    // ... 
} 

这样

when 
    $person:Person(((date > "20-Jan-2015") ... 

结果在一个字符串(!)的

"20-Feb-2015" > "20-Jan-2015" && "20-Feb-2015" < "20-Dec-2015" 

比较甚至可能有时工作,但主要是它不会。您应该使用

class Person { 
    java.util.Date date; 
    // ... 
} 

您需要更改

person.date = new Date(115, 1, 20); // or, preferably, parse a string 

,但你可以离开规则,因为它是; Drools会将字符串转换为日期值(只要它对应于您的区域设置)。

后来经过一些实验后,我发现在编译java.util.Date到String的比较时,6.3.0(可能更早的版本)有一个相当奇怪的行为。

rule x1 when 
    Person(date > "10-Jan-2000")    // OK 
    Person($date:date, date > "10-Jan-2000") // OK 
    Person($date:date, $date > "10-Jan-2000") // Error (types incompatible) 

当程序员可能不依赖于绑定变量的行为与绑定的属性相同时,这是非常令人困惑的。

最后: 不要在您的事实类中使用公共字段。留在Java Beans模型中并声明getter和setter。事实证明,当由于缺少getter而访问(公共)实例变量本身时,Drools没有使用从String到java.util.Date的自动转换。

+0

那么我应该不得不使用日期格式(例如:DateFormat format = new SimpleDateFormat(“dd-MMM-yyyy”,Locale.ENGLISH);)将“2015年12月20日”转换为日期值。 – Hasitha

+0

您只需要将作业更改为'person.date'。 Drools负责转换条件中包含日期的字符串。 - 请参阅我的答案。 – laune

+0

感谢您的支持。但是这给了我一个例外。 (比较操作需要兼容类型,找到类java.util.Date和类java.lang.String) – Hasitha

1

您可以试用org.apache.commons.lang.time.DateUtils。我遇到了同样的问题,这一个为我工作,可能会在你的工作。

import org.apache.commons.lang.time.DateUtils; 

$person: Person((date > DateUtils.parseDate("20-01-2015", "dd-MM-yyyy") && date < DateUtils.parseDate("20-12-2015", "dd-MM-yyyy")) && (call_count >= "299")); 
+0

生成规则条件之前我无法弄清楚条件的左侧和右侧的变量类型是什么。因为我使用数据库动态生成规则。 – Hasitha