流口水查询。他们如何评估和执行?

时间:2015-05-05 18:13:13

标签: java drools business-rules

我在概念验证应用程序中评估Drools 6。我要么误解Drools中的查询是如何工作的,要么是我没有正确实现。有人可以向我解释这种行为:

我有一条规则应该对这样的验证记录起作用:

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

使用有效/无效对象就像使用特征一样,但是文档表明特征功能仍然是实验性的/可能会发生变化,所以我暂时选择了这种替代方案。我认为这个查询很简单。我正在使用无状态会话并像决策服务一样调用引擎。以下代码片段显示了如何调用引擎(目前某些值是硬编码的):

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();

我处理结果如下:

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

在控制台中,我看到了printRn语句,QueryResult大小为0.但是,如果我将查询更改为只收集$ patients:Object(),则QueryResult大小是通过CommandFactory插入的对象数,不包括作为规则的RHS的一部分插入的对象。当我检查审计日志时,我看到确实插入了Valid类型的对象。

为什么我的查询没有返回预期的结果?我是否实施了错误或者我只是误解了查询的工作方式?

谢谢, 詹姆斯

1 个答案:

答案 0 :(得分:1)

添加命令的顺序很重要。添加查询命令是引擎执行该查询的信号,因此插入了事实,并且在进程启动之前运行查询。

反转添加查询和启动进程的行是关键。它现在应该是:

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" ) );