【问题标题】:Drools- Inserting the multiple facts of the same type, with one ruleDrools - 使用一条规则插入相同类型的多个事实
【发布时间】:2012-07-12 16:07:38
【问题描述】:

我是 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

【问题讨论】:

  • 你能粘贴你的规则吗?
  • 小更新,创建了另一个类只是为了测试(具有一个字符串属性的基本类),它工作正常。似乎可能与该特定类有关,以防止在会话中有多个?
  • 默认情况下,Drools 使用标识将对象存储在工作内存中。除非您将配置选项更改为使用相等,否则您可以根据需要/需要拥有尽可能多的同一类的实例。建议:使用 WorkingMemoryConsoleLogger 运行您的测试,将您的审核日志打印到控制台并将控制台日志粘贴到此处...在将每个对象插入工作内存之前打印对象的 scienceName 属性也很好确保它们不为空。

标签: java drools


【解决方案1】:

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

该规则将为每个有 scienceName != null 的对象触发一次。

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

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

【讨论】:

  • 是的,我可能应该尝试一个更通用的示例。我已按上述方式修改了规则,但审计显示没有输出,并且该规则仍然只触发一次。如果我在 while 循环中触发所有规则,它仍然只会触发一次,但会获得正确的信息。
  • 好的,看来问题出在正在使用的库上。我接受您的回答,因为这是编写规则的更有效方式。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多