Drools 中的全局变量更新问题

问题描述 投票:0回答:1

`我是流口水的新手,需要帮助

Java 文件:

kieSession.insert(csaResponseRootDTO);
kieSession.fireAllRules();
System.out.println(kieSession.getGlobal("count")); ==> This is printing as null
kieSession.dispose();

DRL 文件:

rule "Calculate the score" 

when 
$p : DTO() $section : SectionsDTO($sectionName : sectionName, sectionName == "XX") from
$p.sectionsList

$subSection : SubSectionsDTO($subSectionName : subSectionName, subSectionName == "YY") from    $section.subSectionsList

$question : QuestionDTO($questionId : questionId, questionId == "ZZ") from $subSection.questionsList

$questionOption : OptionsDTO($key : key, $selected : selected) from $question.questionnaireOptions

if($key == "yes" && $selected == true) do[yes]
else if($key == "no" && $selected == true) do[no]
    
then
then[yes]
//Accumulate the option values based on the user selected input
double $calc = ConfigContextInitiator.checkBalances(reportConfig, $sectionName,   $subSectionName, $questionId, $key);
System.out.println($calc); // It is printing correctly
kcontext.getKieRuntime().setGlobal("count", $calc);
         
then[no]
double $calc2 = ConfigContextInitiator.checkBalances(reportConfig, $sectionName, $subSectionName, $questionId, $key);
System.out.println($calc2); // It is printing correctly
kcontext.getKieRuntime().setGlobal("count", $calc2);
        
end

** 如果有人提供示例工作代码如何在后续规则中更新全局变量,那就太好了`

drools rule-engine
1个回答
0
投票

这不是使用全局变量的方式。

您可以通过在调用规则时设置对象,然后在规则执行时更新其状态来使用全局变量。全局变量不是基元。

而且你真的不应该在规则本身中搞乱 kcontext。

List<String> fruits = new ArrayList<>();

KieSession session = ruleBase.newStatefulSession();
session.insert(...); // insert data
session.setGlobal( "fruits", fruits);
session.fireAllRules();

System.out.println(fruits); // will now reflect any changes made to it in the rules
global List fruits

rule "On sale fruits"
when
  Cart( $items: items != null )
  Item( onSale == true,
        type == ItemType.FRUIT,
        $name: name ) from $items
then
  fruits.add($name);
  // do other stuff with on-sale fruits
end

假设您传递到工作记忆中的

Cart
看起来像这样:

Cart {
  items: [
    Item{ name: "banana", type: ItemType.FRUIT, onSale: true },
    Item{ name: "blueberry", type: ItemType.FRUIT, onSale: false },
    Item{ name: "kiwi", type: ItemType.FRUIT, onSale: true },
    Item{ name: "artichoke", type: ItemType.VEGETABLE, onSale: true },
    Item{ name: "broccoli", type: ItemType.VEGETABLE, onSale: true }
  ]
}

您会期望 Java 代码 (

System.out.println(fruits)
) 打印(按某种顺序):banana、kiwi。


如果你真的想保留“$count”是什么,你可以使用像

AtomicDouble
这样的东西。或者创建某种业务对象来跟踪副作用并将其设置为全局对象。一般来说,这是从规则中获取结果的非常“老式”的方式——这就是我们在 Drools 5.0 时代做事的方式。

如今,您通常会在规则中对工作记忆中具有状态的某些内容执行某些操作,并以这种方式跟踪副作用。例如。当您触发规则并直接修改它时,将某种

Balances
对象传递到工作内存中。这还允许您编写阻止对这些值进行更改的规则。 (因为您不能编写关闭值或更改全局变量的规则。)

© www.soinside.com 2019 - 2024. All rights reserved.