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

时间:2021-09-06 15:47:20

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:

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

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.

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

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 个解决方案

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

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