【问题标题】:Drools: Get identifier from LHS patternDrools:从 LHS 模式中获取标识符
【发布时间】:2016-03-22 12:14:41
【问题描述】:

我正在使用 Drools 6.3.0 Final。假设我有这样的规则

rule "Child of Person over 18"
when
    $person : Person(age > 18)
    $child : from $person.children
then
end

让我们进一步假设我使用此规则构建我的 KieSession,添加一些事实,现在我想知道在所有规则中使用的标识符/在与我的事实匹配的所有规则中。

所以我想在这里得到的是 $person 和 $child。

我知道我可以获取使用 AgendaEventListener 触发的规则,并且从事件中我可以获取规则的名称,以及 $person 和 $child 的对象。但是我找不到从匹配项中获取标识符 $person 和 $child 的方法。使用调试器,我可以看到信息在那里......实际上我从事件中得到的规则是一个 RuleImpl,它有一个 lhsRoot,我可以在其中找到该信息......但这听起来比它应该的要复杂得多是而不是预期的方式。

所以我想知道是否没有更好的方法。

【问题讨论】:

  • 您想如何处理这些纯属本地规则的信息?
  • RuleImpl 和 GroupElement 是非公共 API 的类,这意味着它们如有更改,恕不另行通知。标准建议是避免将任何严肃的应用程序编程基于这些类。
  • 我需要为结果提供我自己的系统,这就是为什么我需要匹配的值和规则中使用的名称。我希望有这方面的公共 API,但如果没有,那么它必须是内部的
  • 奇怪 - 好像 Java 不足以满足所有需求。 - 但是将 RHS 编写为某个静态方法的单个调用,将您需要的所有绑定变量作为参数传递给“您自己的结果”不是更容易和更安全吗?
  • 你的意思是像 record("Child of Person over 18", "$person", $person, "$child", $child)?可以肯定,是的。我还有一些我没有提到的其他要求,禁止直接在规则中使用后果。稍后,规则将从与 DRL 完全不同的来源生成。当我们到了那个时候,我也不会再有提取标识符的问题了。

标签: drools


【解决方案1】:

您的要求可以通过使用 Drools 的公共 API 轻松实现。您正在寻找正确的位置 (AgendaEventListener),但 Match.getObjects() 不是您需要的。您需要的是Match.getDeclarationIds()(获取标识符列表)和Match.getDeclarationValue(String id)(获取每个标识符的值)的组合。例如,在控制台中记录此信息的 AgendaEventListener 如下所示:

import org.kie.api.event.rule.BeforeMatchFiredEvent;
import org.kie.api.event.rule.DefaultAgendaEventListener;

...

ksession.addEventListener(new DefaultAgendaEventListener() {

    @Override
    public void beforeMatchFired(BeforeMatchFiredEvent event) {

        String ruleName = event.getMatch().getRule().getName();
        List<String> declarationIds = event.getMatch().getDeclarationIds();

        System.out.println("\n\n\tRule: "+ruleName);

        for (String declarationId : declarationIds) {
            Object declarationValue = event.getMatch().getDeclarationValue(declarationId);

            System.out.println("\t\tId: "+declarationId);
            System.out.println("\t\tValue: "+declarationValue);
        }
        System.out.println("\n\n");
    }
});

正如@laune 提到的,您还可以在规则本身的 RHS 中获取激活规则的匹配实例。在这种情况下,可以通过 drools.getMatch() 访问 Match 对象。

希望对你有帮助,

【讨论】:

  • 我的 getDeclarationIds() 问题是,在我的情况下它似乎返回一个空列表
猜你喜欢
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多