0

我不明白这段drl代码的一些部分,但我将在这里发布一个问题:

https://github.com/kiegroup/kogito-examples/blob/stable/ruleunit-quarkus-example/src/main/resources/org/kie/kogito/queries/RuleUnitQuery.drl

完整的 drl 代码在这里:

package org.kie.kogito.queries;
unit LoanUnit;
import org.kie.kogito.queries.LoanApplication;
import org.kie.kogito.queries.AllAmounts;
rule SmallDepositApprove when
    $l: /loanApplications[ applicant.age >= 20, deposit < 1000, amount <= 2000 ]
then
    modify($l) { setApproved(true) };
end
rule SmallDepositReject when
    $l: /loanApplications[ applicant.age >= 20, deposit < 1000, amount > 2000 ]
then
    modify($l) { setApproved(false) };
end
rule LargeDepositApprove when
    $l: /loanApplications[ applicant.age >= 20, deposit >= 1000, amount <= maxAmount ]
then
    modify($l) { setApproved(true) };
end
rule LargeDepositReject when
    $l: /loanApplications[ applicant.age >= 20, deposit >= 1000, amount > maxAmount ]
then
    modify($l) { setApproved(false) };
end
rule NotAdultApplication when
    $l: /loanApplications[ applicant.age < 20 ]
then
    modify($l) { setApproved(false) };
end
query FindApproved
    $l: /loanApplications[ approved ]
end
query FindNotApprovedIdAndAmount
    /loanApplications[ !approved, $id: id, $amount : amount ]
end
rule AllAmounts
when
    accumulate ( $a : /loanApplications ; $sum : sum($a.amount))
then
    allAmounts.add(new AllAmounts($sum));
end
query FindAllApplicationAmounts
    $a : /allAmounts
end

在这行代码allAmounts.add(new AllAmounts($sum));中,我们是否AllAmounts用这段代码实例化了一条新规则?规则AllAmounts似乎没有带任何参数,那么如何$sum传递给规则呢?

4

1 回答 1

1

这里发生的事情是您正在使用 RuleUnit 提供的方法LoanUnit,即allAmountsDataStore:

public DataStore<AllAmounts> getAllAmounts()

有问题的规则是这样的:

rule AllAmounts
when
    accumulate ( $a : /loanApplications ; $sum : sum($a.amount))
then
    allAmounts.add(new AllAmounts($sum));
end

逐行,这是正在发生的事情:

rule AllAmounts
when
    accumulate ( 
                 $a : /loanApplications ; // for each loan application ($a)
                 $sum : sum($a.amount)    // sum up the amount; assign output to $sum
                )
then
    allAmounts.add(
                   new AllAmounts($sum) // create a new AllAmounts object
    );                                  // and add it to the AllAmounts datastore (working memory)
end

回想一下,Drools 基于 Java Bean 命名约定“查找”属性——因此,当您引用类中的某个字段时,它首先检查该字段是否存在“getter”。这就是使用这种令人困惑的语法发生的情况:即使我们从未声明过一个名为的变量allAmounts,我们在 RuleUnit 中确实getAllAmounts有一个 getter,名为... 这就是我们得到的。

DataStore 是 Kogito 使信息可用于其规则的方式之一。在Kogito 文档中,它是这样定义的:

DataStore:一个可写的存储选项,用于添加或删除数据,然后通知所有订阅者可变数据已被修改。规则可以对传入值进行模式匹配,并更新或删除可用值。对于熟悉 Drools 的用户来说,这个选项相当于一个输入点的类型化版本。实际上,aDataStore<Object>相当于一个老式的入口点。

请注意,Drools 也有一个DataSource非常相似的界面。你可以以同样的方式思考它们。两者基本上都是围绕工作内存中特定类型对象集合的包装器。所以这条规则的有效作用是创建一个新AllAmounts对象,然后添加到表示工作内存中数据的 DataStore。

我们绝不会执行“按名称”的规则——这对示例编写者来说是一个不幸的命名选择。规则不是像这样按需执行的,它们是基于事实匹配条件子句以一系列方式执行的。


参考

  • 您可以在此处阅读 Drools 文档中有关 RuleUnits 的更多信息。
  • Drools 数据源也在此处的 Drools 文档中进行了讨论。
  • /loanApplication语法是 OOPath 表示法,它似乎在任何地方都没有专门的文档,但 Drools 文档中也有它的示例。
  • 我无法找到 Kogito DataStore 的 Javadoc,但在此处的 Kogito 文档中对其进行了讨论。
于 2021-08-22T17:44:41.967 回答