2012-07-12 88 views
0

我对Drools非常新,我已经完成了一些在线发现的教程并阅读了文档。我相信我要解释的是我已经错过了一个微不足道的解决方案,但无论如何我都会解决它。Drools-插入同一类型的多个事实,使用一个规则

我在我的drools文件和一个从文本文件读取其信息的对象中有一条规则。

代码看起来与此类似:

public static final void main(String[] args) { 
     try { 
      ObjectArchive arch = ArchiveFactory.openArchive(new File("dwc.txt")); 
      Iterator<Object> iter = arch.iteratorDwc(); 

      // load up the knowledge base 
      KnowledgeBase kbase = readKnowledgeBase(); 
      StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); 
      KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); 
      while(iter.hasNext()) { 
       Object dwcRecord = iter.next(); 
       ksession.insert(dwcRecord); 
      } 
      System.out.println(ksession.getFactCount()); 
      ksession.fireAllRules(); 
      logger.close(); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 
    } 

    private static KnowledgeBase readKnowledgeBase() throws Exception { 
     KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
     kbuilder.add(ResourceFactory.newClassPathResource("dwcrules.drl"), 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; 
    } 

我有检查,如果说对象的属性不为空,并打印出的对象,如果这是真的一个简单的规则文件。

现在,问题所在。

如果我添加一个对象(没有while循环),那么规则被触发,一切都很好。但是,如果我将多个对象添加到会话中,然后触发规则,它往往只抓取最后一个,或者触发但打印出一个空值。

那么,为什么我无法添加同一类型的多个事实呢?或者我错过了什么,阻止我能够在多个事实上启动相同的规则?

在此先感谢。

编辑:对不起,这里是规则:

rule "Scientific Name" 
when 
    dwc : Object(dwc.getScientificName != null) 
then 
    System.out.println(dwc); 
end 
+0

能否请您贴上您的规则? – 2012-07-12 16:27:36

+0

小更新,创建另一个类只是为了测试(具有一个字符串属性的基本类),它工作正常。似乎有可能会与该特定班级有关,防止在会话中有多个? – 2012-07-13 14:35:45

+0

默认情况下,Drools使用身份将对象存储在工作内存中。除非您将配置选项更改为使用相等性,否则您可以根据需要拥有同一个类的多个实例。建议:使用WorkingMemoryConsoleLogger运行测试,将您的审计日志打印到控制台中,并将控制台日志粘贴到此处......在将每个对象的对象的scientificName属性插入工作内存之前,先打印对象的scientificName属性也不错确定它们不是空的。 – 2012-07-13 14:43:14

回答

0

我不知道到底发生了什么,因为我没有你的对象文件运行测试,但只要打开你的日志文件在eclipse审计视图中,您将立即看到插入的对象以及哪些对象激活规则。

该规则将针对具有scientificName!= null的每个对象触发一次。

此外,如果您有更专门的类/接口定义getScientificName()方法,则您的规则不应该试图匹配Object。举例来说,如果你有一个名为“MyDwcClass”类,你应该写这样的规则:

rule "Scientific Name" 
when 
    dwc : MyDwcClass(scientificName != null) 
then 
    System.out.println(dwc); 
end 
+0

是的,我应该尝试一个更通用的例子。我已经修改了上面的规则,但是审计没有显示输出,规则仍然只被触发一次。如果我在while循环内激发所有规则,它仍然只触发一次,但获得正确的信息。 – 2012-07-13 08:37:56

+0

好吧,看来问题在于正在使用的库。我接受你的回答,因为它是编写规则的更有效方式。谢谢您的帮助! – 2012-07-17 07:27:36

相关问题