Drools Queries. How are they evaluated and executed?

喜欢而已 提交于 2019-12-10 22:08:14

问题


I am evaluating Drools 6 in a proof of concept application. I am either misunderstanding how the queries in Drools work or I have not implemented something properly. Could someone explain this behavior to me:

I have a rule that is supposed to act on validated records like this:

rule "Patient Intake: Valid new Patients without a Medical History require a Review"
    ruleflow-group "Patient Intake"
    when
        $patient : Patient( status == PatientStatus.NEW )
        not Invalid( value == $patient )
    then
        modify( $patient ){
            setStatus( PatientStatus.PENDING_REVIEW )
        };

        insert( new Valid( $patient ) );
    end

query "Intake Results"
    Valid( $patients : value )
end

The Valid/Invalid objects are used like one would use a trait, however the documentation indicated that the trait feature was still experimental/subject to change, so I chose this alternative for the time being. The query is straightforward enough I think. I am using a stateless session and invoking the engine like a decision service. The following snippet of code shows how the engine is invoked (some values are hardcoded at the moment):

StatelessKieSession kSession = kContainer.newStatelessKieSession( "TestKSession" );
KieRuntimeLogger auditLog = KieServices.Factory.get().getLoggers().newFileLogger( kSession, "audit" );
kSession.setGlobal( "logger", logger );

List<Command> commands = new ArrayList<Command>();
commands.add( CommandFactory.newInsertElements( request.getAllFacts() ) );
commands.add( CommandFactory.newQuery( "$patients", "Intake Results" ) );
commands.add( CommandFactory.newStartProcess( "x.y.z.intake" );

ExecutionResults results = kSession.execute( CommandFactory.newBatchExecution( commands ) );
auditLog.close();

And I process the results like this:

    private void processResults( ExecutionResults results ) {
        QueryResults qr = (QueryResults) results.getValue( "$patients" );
        for ( QueryResultsRow row : qr ) {
            // ... this code is never executed
        }
}

In the console I see the println statement that the QueryResult size is 0. However, if I change the query to just collect $patients : Object() the QueryResult size is the number of objects inserted via the CommandFactory and does not include the objects inserted as part of the RHS of the rule. When I check the audit log i see that an object of type Valid is indeed inserted.

Why is my query not returning the intended results? Did I implement something wrong or am I just misunderstanding how queries work?

Thanks, James


回答1:


The order that the commands are added matters. Adding the query command is a signal to the engine to execute that query, therefore the facts were being inserted and the query run BEFORE the process was started.

Reversing the lines where the queries were added and the process started was the key. It should now read:

List<Command> commands = new ArrayList<Command>();
commands.add( CommandFactory.newInsertElements( request.getAllFacts() ) );
commands.add( CommandFactory.newStartProcess( "x.y.z.intake" );
commands.add( CommandFactory.newQuery( "$patients", "Intake Results" ) );


来源:https://stackoverflow.com/questions/30060305/drools-queries-how-are-they-evaluated-and-executed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!