2015-11-03 3 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(); 

Но не печатать «Beep». Я думаю, что условия не совпадают, но я не могу понять, почему это происходит. Как я могу сравнить даты в слюни?

Моего фактический набор правил,

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 преобразует строку в значение Date (при условии, что она соответствует вашей настройке локали).

Позже После некоторых экспериментов я обнаружил, что 6.3.0 (и, возможно, более ранние версии) имеют довольно странное поведение при компиляции сравнений java.util.Date с String.

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 и объявляйте геттеры и сеттеры. Оказывается, Drools не использует автоматическое преобразование из String в java.util.Date, когда доступ к переменной (public) экземпляра из-за отсутствия геттера.

+0

, тогда мне нужно преобразовать «20-Dec-2015» в значение даты с использованием формата даты (например: DateFormat format = new SimpleDateFormat («dd-MMM-yyyy», Locale.ENGLISH);). – 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