有没有办法让 drools 变量在规则之间保持不变?
Is there a way to have a drools variable persist between rules?
我想做的是将单独存储在全局 outputMap 中的各种字符串连接起来。但是,我有一些限制。
- 我不允许将任何对添加到没有“输出”键的 outputMap 中。
- 除了 outputMap 之外,我不允许 insert/set 任何全局变量进入 kie 会话。
- 以下以字母结尾的子规则需要定义为单独的规则。
所以我用另一个没有被 kie 会话设置的全局变量尝试了以下解决方案。
import java.util.*
global java.util.Map outputMap;
global java.util.List concatList;
rule 101A
salience 3
when
$v1:Map()
$fruit:String() from $v1.get("Strawberries");
then
outputMap.put("Output", $fruit);
if(concatList == null)
{
concatList = new List<String>();
}
concatList.add($fruit);
end
rule 101B
salience 2
when
$v1:Map()
$fruit:String() from $v1.get("Cherries");
then
outputMap.put("Output", $fruit);
if(concatList == null)
{
concatList = new List<String>();
}
concatList.add($fruit);
end
rule 101
salience 1
when
$v1:Map()
$fruit:String() from $v1.get("All");
then
String s = "";
for(int i=0; i<concatList.size(); ++i)
{
s+=concatList.get(i);
}
outputMap.put("Output", s);
end
此方法的问题是全局 concatList 的值似乎在每次执行规则后都会重置,因为我无法将其插入到 kie 会话中,而且由于我有第一个约束,我不能简单地插入它进入输出映射并稍后检索它。
我的问题是,有没有办法让变量在规则之间保持不变,而无需在 kie 会话中定义它?
TLDR: 以上问题
谢谢
你不能那样依赖全局变量。
通常,您会通过调用 insert
、update
和 modify
来更改工作内存。
你的例子有点奇怪(这张奇怪的“草莓”地图是什么->???),但它通常看起来像这样:
rule "Init"
when
not( ArrayList() )
then
insert( new ArrayList() )
end
rule "Strawberries"
salience 1
when
$concatList: ArrayList()
Map( $fruit: this["Strawberries"] )
then
$concatList.add($fruit)
end
rule "Cherries"
salience 1
when
$concatList: ArrayList()
Map( $fruit: this["Cherries"] )
then
$concatList.add($fruit)
end
rule "Output"
when
$concatList: ArrayList()
then
String s = String.join(";", $concatList);
outputMap.put("Output", s);
end
在 Init
规则中,如果 ArrayList 尚不存在,我将其插入到工作内存中。然后“草莓”和“樱桃”规则将 Map 中的任何值添加到该列表中。最后,输出规则连接所有值并将其推入“outputMap”全局。
如果您需要您的规则了解工作内存中对象的更改,您可以调用 modify
或 update
。修改将更改工作内存中的对象并使用新值重新评估后续规则。更新就像用新值重新调用“消防规则”。
我想做的是将单独存储在全局 outputMap 中的各种字符串连接起来。但是,我有一些限制。
- 我不允许将任何对添加到没有“输出”键的 outputMap 中。
- 除了 outputMap 之外,我不允许 insert/set 任何全局变量进入 kie 会话。
- 以下以字母结尾的子规则需要定义为单独的规则。
所以我用另一个没有被 kie 会话设置的全局变量尝试了以下解决方案。
import java.util.*
global java.util.Map outputMap;
global java.util.List concatList;
rule 101A
salience 3
when
$v1:Map()
$fruit:String() from $v1.get("Strawberries");
then
outputMap.put("Output", $fruit);
if(concatList == null)
{
concatList = new List<String>();
}
concatList.add($fruit);
end
rule 101B
salience 2
when
$v1:Map()
$fruit:String() from $v1.get("Cherries");
then
outputMap.put("Output", $fruit);
if(concatList == null)
{
concatList = new List<String>();
}
concatList.add($fruit);
end
rule 101
salience 1
when
$v1:Map()
$fruit:String() from $v1.get("All");
then
String s = "";
for(int i=0; i<concatList.size(); ++i)
{
s+=concatList.get(i);
}
outputMap.put("Output", s);
end
此方法的问题是全局 concatList 的值似乎在每次执行规则后都会重置,因为我无法将其插入到 kie 会话中,而且由于我有第一个约束,我不能简单地插入它进入输出映射并稍后检索它。
我的问题是,有没有办法让变量在规则之间保持不变,而无需在 kie 会话中定义它?
TLDR: 以上问题
谢谢
你不能那样依赖全局变量。
通常,您会通过调用 insert
、update
和 modify
来更改工作内存。
你的例子有点奇怪(这张奇怪的“草莓”地图是什么->???),但它通常看起来像这样:
rule "Init"
when
not( ArrayList() )
then
insert( new ArrayList() )
end
rule "Strawberries"
salience 1
when
$concatList: ArrayList()
Map( $fruit: this["Strawberries"] )
then
$concatList.add($fruit)
end
rule "Cherries"
salience 1
when
$concatList: ArrayList()
Map( $fruit: this["Cherries"] )
then
$concatList.add($fruit)
end
rule "Output"
when
$concatList: ArrayList()
then
String s = String.join(";", $concatList);
outputMap.put("Output", s);
end
在 Init
规则中,如果 ArrayList 尚不存在,我将其插入到工作内存中。然后“草莓”和“樱桃”规则将 Map 中的任何值添加到该列表中。最后,输出规则连接所有值并将其推入“outputMap”全局。
如果您需要您的规则了解工作内存中对象的更改,您可以调用 modify
或 update
。修改将更改工作内存中的对象并使用新值重新评估后续规则。更新就像用新值重新调用“消防规则”。