我是 Drools 的新手。我想知道是否可以使用某种可以在 Windows 命令行(shell/cmd)中输入的命令来编译 .drl 文件。我查看了 drools 发行版附带的二进制文件,但我无法找到编译 .drl 文件的方法。我对这样的命令感兴趣的原因是我想编写一个 ant 构建文件,它将编译我的 java 类和规则并创建一个 jar。这个 jar 应该是自给自足的,即从命令行运行 jar 应该运行主程序,该程序在会话中传递事实,从而自动执行对这些事实进行操作的规则。
我是 drools 的新手,并给出了一个条件 (Condition) 和一个布尔变量 "a" ,我想用 drools 创建以下规则:
if (Condition)
{
a = true;
}
else
{
a = false;
}
Run Code Online (Sandbox Code Playgroud)
最好的方法是什么?
目前我有两个选择:
1.用条件而不是条件创建2条规则(如果......那么......,如果不是......那么......)
rule "test"
where
$o: Object( Condition)
then
$o.a = true;
end
rule "test2"
where
$o: Object( not Condition)
then
$o.a = false
end
Run Code Online (Sandbox Code Playgroud)
2.默认将变量a设置为false,然后触发规则
rule "test"
no loop
salience 100
where
$o: Object()
then
$o.a = false;
end
rule "test"
where
$o: Object( not Condition)
then
$o.a = true;
end
Run Code Online (Sandbox Code Playgroud) 我正在从事一个小型 Drools 项目,因为我想了解有关使用规则引擎的更多信息。我有一个名为的类Event
,它具有以下字段:
String tag;
可以是任何字符串的标签。long millis;
一个时间戳。(实际上,这是从LocalDate
同样在Event
. 中的 JodaTime字段转换而来的。)int value;
我想要推理的值。我Event
在我的知识库中插入了数百个实例,现在我想获取标记为"OK"
. 我想出了以下代码,该代码有效:
rule "Three most recent events tagged with 'OK'"
when
$e1 : Event( tag == "OK",
$millis1 : millis )
$e2 : Event( tag == "OK",
millis < $millis1, $millis2 : millis )
$e3 : Event( tag == "OK",
millis < $millis2, $millis3 : millis )
not Event( tag == "OK",
millis > $millis1 ) …
Run Code Online (Sandbox Code Playgroud) 我在学区工作,我们计划使用 Drools 为学区组成学校的学生群体实施以下类型的规则:
所有这些规则都可以使用 Drools 专家来简单地表达。此外,学生的规则处理不需要同步。我有几个关于实现这一点的最佳方法的问题。
从一个角度来看,这可以看作是一个事件流的监控系统。这让我想到创建一个有状态的会话,每个新事件都将插入其中。然而,这些事件发生在 9 个月的过程中并且相对不频繁。此外,我们可以为每个学校或每个学生建立一个会话。
另一种选择是在为该学生处理事件后为该学生保留一个会话。当下一个事件到来时,我们将从存储中检索他们的会话并插入新的事实。这样我们就不需要为引擎的每次运行检索所有事实来获取学生的状态。会支持这样的配置吗?这样做有什么缺点吗?
第三种方法是通过检索规则需要运行的所有其他事实、创建新的 KnowledgeSession 并运行规则来响应学生的新事实。
任何关于什么可能是最好的方法的建议将不胜感激。
戴夫
我是 Drools 的新手。我已经将 Drools 与 jsp 集成在一起。现在我想知道 Drools 是否有任何 GUI 来运行其应用程序?谢谢
我有两个 int 字段的简单 JAVA bean:'a' 和 'b'。
我有两个规则:
rule "First rule"
salience 10
when
$bean : Bean ( a == 1)
then
$bean.setB(10);
end
rule "Second rule"
salience 20
when
$bean : Bean ( a == 1)
then
$bean.setB(20);
end
Run Code Online (Sandbox Code Playgroud)
实际结果:首先触发“第二条规则”(更高的显着性),第二条触发“第一条规则”。
预期结果:仅触发一条规则(具有最高显着性)。其他规则被忽略。这该怎么做?在 Drools 中可能吗?我正在使用 Drools 6.0.0 Final。
要求: 1. 我不能使用“激活组”。2. 我不想在每个 bean 上使用 'retract'。
更新
真的很感谢你的回答。
也许我应该详细描述我的问题。我有一套 1500 条规则。每条规则:
我想得到什么? 当我有冲突(输入事实与两个或更多规则匹配)时,我只想触发一个具有最高显着性的规则。应该忽略这一事实的其他匹配规则。最重要的是性能 - 这应该尽可能快地工作。
我所做的? 目前我有两种解决方案,但我不知道哪个更好,或者我应该以不同的方式解决这个问题。
解决方案 1 …
我们最近从 Drools 5 升级到 Drools 6,但遇到了令人不安的冲突问题。
我们已经kie-ci
导入到out项目中。kie-ci
带进来sisu-guava
。sisu-guava
更改了谷歌番石榴中某些类的可访问性。不幸的是,它使用与 google 的 guava 相同的包名。
由于我们在项目中使用了 google 的 guava,因此我们遇到了类冲突。尝试sisu-guava
从项目中删除(使用 maven 排除)会导致可访问性异常,因为 kie-ci 代码尝试访问sisu-guava
在 google guava中公开但私有的类。
知道如何解决这个问题。
我有一个问题理解为什么exists
关键字是必要的。我有以下规则:1)
rule "normal"
when
Bus( seats > 20 )
then
System.out.println("There is a 20+ bus);
end
Run Code Online (Sandbox Code Playgroud)
2)
rule "with exists"
when
exists Bus( seats > 20 )
then
System.out.println("There is a 20+ bus existing...);
end
Run Code Online (Sandbox Code Playgroud)
第一条规则的 LHS 与第二条规则有何不同?
谢谢!
我想在 drools 规则文件 (mvel) 中声明一个全局变量。这是因为此全局变量在所有规则中都用作另一个函数的参数。我可以很容易地在每次调用函数时显式地传递这个字符串,但是如果字符串发生变化,这会变得很困难。
我以为我可以做一个:
global String someStr = "some string";
Run Code Online (Sandbox Code Playgroud)
但是在编译时,我得到:
[11,31]: [ERR 107] Line 11:31 mismatched input '=' expecting one of the following tokens: '[package, import, global, declare, function, rule, query]'.
Run Code Online (Sandbox Code Playgroud)
很明显,我不能这样分配。我似乎也无法在该类中声明一个类和一个字符串以通过该类进行引用。
所以我发现我可以做一些看起来很愚蠢的事情:
global String someStr;
rule "Initialize"
when
then
someStr = "some string";
end
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但是,每次此规则匹配(始终)时,这都会记录以仅分配全局。
有没有更好的方法让我失踪???
我正在使用单线程 drools 项目作为第一匹配策略/条件评估引擎。我正在使用以下代码从 kieContainer 获取 kieSession,并根据条件评估谓词。
KieContainer currentContainer = kieContainer.get();
StatelessKieSession newKIESession = currentContainer.newStatelessKieSession();
newKieSession.execute(predicate);
Run Code Online (Sandbox Code Playgroud)
对于给定的请求,评估大约需要 10 毫秒。但是,当我使用 10 个线程时,为了提高性能,这些请求中的每一个都开始花费大约 100 毫秒,有效地为我提供了相同的性能和更多的线程。
我应该为每个处理线程生成一个新容器,而不是从现有容器生成一个新会话吗?
//SEE LAST LINE BELOW
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
KieFileSystem kfs = ks.newKieFileSystem();
byte[] drlAsBytes = retrieveDRLResource();
kfs.write(ResourceFactory.newByteArrayResource(drlAsBytes).setTargetPath(DROOLS_DEFAULT_PATH));
KieBuilder kb = ks.newKieBuilder(kfs);
kb.buildAll(); // kieModule is automatically deployed to KieRepository if successfully built.
if (kb.getResults().hasMessages(Level.ERROR)) {
throw new PolicyServiceException("Build Errors:\n" + kb.getResults().toString());
}
//******* SHOULD THIS BE DONE FOR EACH PROCESSING …
Run Code Online (Sandbox Code Playgroud)