Drools 不匹配从反序列化获得的嵌套对象

Drools not matching nested object obtained from deserialization

我正在尝试在 Drools 中创建一个规则,该规则将基于假设的学生获得直接 As 触发。

import Student
import Semester
import java.util.*

dialect "mvel"

rule "straight As1"
    when
        $s : Student(
            grades != null,
            $g : grades
        )
        forall(
            Semester(reading == "A", writing == "A", math == "A") from $g
        )
    then
        System.out.println($s.getId() + ": s all As1: " + $s);
        System.out.println($s.getId() + ": g all As1: " + $g);
end

rule "straight As2"
    when
        $s : Student(
            grades != null,
            $g : grades
        )
        $a : List(size() == $g.size) from
            collect (Semester(reading == "A", writing == "A", math == "A") from $g)
    then
        System.out.println($s.getId() + ": s all As2: " + $s);
        System.out.println($s.getId() + ": g all As2: " + $g);
end

这个输出:

001: s all As1: Student{id='001', grades=[{writing=A, reading=A, math=A}, {writing=A, reading=A, math=A}], name='Albert'}
001: g all As1: [{writing=A, reading=A, math=A}, {writing=A, reading=A, math=A}]
----------------
002: s all As1: Student{id='002', grades=[{writing=B, reading=B, math=B}], name='Bob'}
002: g all As1: [{writing=B, reading=B, math=B}]

这里的问题是 Bob 没有 All As。 我不确定如何让 straight As 规则中的任何一个为 Albert 而不是Bob - As1 尝试触发所有内容,而 As2 尝试不触发任何内容。

我已经能够编写规则来根据名称进行过滤。在调试时,我在 getGrades() 触发器上设置了断点...但是在 getMath()getWriting()getReading() 上的断点中有 none 已命中。

Student 对象(收紧并删除 toString())是:

public class Student {
    private String id;
    private List<Semester> grades;
    private String name;

    public Student() { }
    public String getName() { return name; }
    public String getId() { return id; }
    public List<Semester> getGrades() { return grades; }
    public void setName(String name) { this.name = name; }
    public void setId(String id) { this.id = id; }
    public void setGrades(List<Semester> grades) { this.grades = grades; }
}

相应的 Semester 对象(也收紧并删除了 toString()):

public class Semester {
    private String reading;
    private String writing;
    private String math;

    public Semester() { }
    public String getReading() { return reading; }
    public String getWriting() { return writing; }
    public String getMath() { return math; }
    public void setReading(String reading) { this.reading = reading; }
    public void setWriting(String writing) { this.writing = writing; }
    public void setMath(String math) { this.math = math; }
}

这些对象是用代码片段实例化的:

YamlReader reader = new YamlReader(new FileReader(file));
Student student = reader.read(Student.class);
System.out.println(student.toString());
rv.add(student);

和一个 yaml 对象,例如:

id:
  001
grades:
  -
    reading: A
    writing: A
    math: A
  -
    reading: A
    writing: A
    math: A
name:
  Albert

使用最简单的方法:

rule "straight As1"
when
    $s : Student( grades != null, $g : grades )
    not Semester(reading != "A" || writing != "A" || math != "A") from $g
then
    System.out.println($s.getId() + ": s all As1: " + $s);
    System.out.println($s.getId() + ": g all As1: " + $g);
end

我的主课,使用你的学生和学期:

public class Main {
private KieSession kieSession;
private KieScanner kieScanner;

public void build() throws Exception {
    KieServices kieServices = KieServices.Factory.get();
    KieFileSystem kfs = kieServices.newKieFileSystem();

    FileInputStream fis = new FileInputStream( "alla/alla.drl" );
    kfs.write( "src/main/resources/simple.drl",
                kieServices.getResources().newInputStreamResource( fis ) );

    KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();

    Results results = kieBuilder.getResults();
    if( results.hasMessages( Message.Level.ERROR ) ){
        System.out.println( results.getMessages() );
        throw new IllegalStateException( "### errors ###" );
    }

    KieContainer kieContainer =
    kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );

    KieBase kieBase = kieContainer.getKieBase();

    kieSession = kieBase.newKieSession();
}

public void exec(){
    Student albert = new Student();
    albert.setName( "Albert" );
    albert.setId( "001" );
    albert.getGrades().add( new Semester( "A", "A", "A" ) );
    albert.getGrades().add( new Semester( "A", "A", "A" ) );
    kieSession.insert( albert );

    Student bob = new Student();
    bob.setName( "Bob" );
    bob.setId( "002" );
    bob.getGrades().add( new Semester( "B", "B", "B" ) );
    kieSession.insert( bob );

    kieSession.fireAllRules();
}

public static void main( String[] args ) throws Exception {
Main m = new Main();
    m.build();
    m.exec();
}
}