从有状态的drools会话中获取事实

我试图从规则中获取新的插入事实:

import com.neu.als.thesis.db.beans.FLTBean import com.neu.als.thesis.db.beans.StudentBean rule "Excellent" no-loop when $m: FLTBean ( listeningScore > 85 && listeningScore < 101 ) then StudentBean studentBean = new StudentBean(); studentBean.setKnowledgeLevel( "Excellent" ); insert( studentBean ); end 

要从有状态会话中获取内容,我应该这样做:

 protected Collection findFacts( final StatefulKnowledgeSession session, final String factClass ) { ObjectFilter filter = new ObjectFilter() { @Override public boolean accept( Object object ) { return object.getClass().equals( factClass ); } }; Collection results = session.getObjects( filter ); return results; } 

鉴于我已经设置代码来读取规则,下一步我做的是:

 protected void processFacts( KnowledgeBase aKnowledgeBase, Object aBean ) { StatefulKnowledgeSession ksession = aKnowledgeBase.newStatefulKnowledgeSession(); ksession.insert( aBean ); ksession.fireAllRules(); Collection result = findFacts( ksession, "StudentBean" ); ksession.dispose(); for( Object test : result ) { System.out.println( test == null ); System.out.println( test ); } } 

为什么我没有从对象得到任何回应? 它不打印任何东西。 没有堆栈跟踪,没有错误。 我甚至检查它是否为null。 但仍然没有回应。 我究竟做错了什么?

更新:

这是读取.drl文件的方法。

 protected KnowledgeBase readKnowledgeBase( String aRuleFileName ) throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add( ResourceFactory.newClassPathResource( aRuleFileName, getClass() ), ResourceType.DRL ); KnowledgeBuilderErrors errors = kbuilder.getErrors(); if( errors.size() > 0 ) { for( KnowledgeBuilderError error : errors ) { System.err.println( error ); } throw new IllegalArgumentException( "Could not parse knowledge." ); } KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() ); return kbase; } 

调用processFacts方法的是这个

 public String evaluateConceptKnowledgeLevel( double FLTmark ) { String knowledgeLevel = null; // test InferenceEngine ie = new InferenceEngine(); KnowledgeBase kbase; try { kbase = ie.readKnowledgeBase( "KnowledgeLevel.drl" ); FLTBean bean = new FLTBean(); bean.setListeningScore( FLTmark ); ie.processFacts( kbase, bean ); } catch( Exception e ) { e.printStackTrace(); } // up to here return knowledgeLevel; } 

一些选择……

传入简单名称而不是完整的类名。

更改

 Collection result = findFacts( ksession, "com.neu.als.thesis.db.beans.StudentBean" ); 

 Collection result = findFacts( ksession, "StudentBean" ); 

更改’accept’方法以比较完整的类名。

更改

  public boolean accept( Object object ) { return object.getClass().getSimpleName().equals( factClass ); } 

  public boolean accept( Object object ) { return object.getClass().getName().equals( factClass ); } 

更改find​​Facts方法以将实际类作为参数并进行比较。

更改

 protected Collection findFacts( final StatefulKnowledgeSession session, final String factClass ) { ObjectFilter filter = new ObjectFilter() { @Override public boolean accept( Object object ) { return object.getClass().getSimpleName().equals( factClass ); } }; Collection results = session.getObjects( filter ); return results; } 

 protected Collection findFacts( final StatefulKnowledgeSession session, final Class factClass ) { ObjectFilter filter = new ObjectFilter() { @Override public boolean accept( Object object ) { return object.getClass().equals( factClass ); } }; Collection results = session.getObjects( filter ); return results; } 

假设您的事实都是Java类,那么比较类的第3个选项是更好的选择。 如果使用声明的类型,则简单名称很有用,因为您不太可能引用Drools生成的实际类。

在您测试这些内容时,Drools API还提供了一个不带参数的session.getObjects()方法。 通过调用,您将获得对工作记忆中所有事实的引用,无论它们是什么。 在编写filter时,使用它来向自己certificate预期的事实在工作记忆中,然后添加过滤,以便您可以根据其类和属性选择特定事实并不是一个坏主意。