设为首页 | 收藏本站
185 1521 8668

DMN中的查找表

发表时间:2025-04-02 17:48作者:Together规则引擎
文章附图

查找表是决策模型中常见的逻辑模式。为了对它们进行建模,初学者自然而然地倾向于决策表,这是最熟悉的值表达类型。但决策表几乎从来都不是正确的方法。一个基本原因是,我们通常希望能够在不创建新版本的决策模型的情况下修改表数据,而对于决策表,您无法做到这一点。另一个原因是决策表必须手动键入,而普通数据表可以从Excel上传、存储在云数据存储中,或以编程方式以JSON或XML格式提交。

对查找表进行建模的最佳方法是在FEEL数据表上使用筛选表达式。有几种方法可以对数据表进行建模-作为提交的输入数据、云数据存储、零输入决策或计算决策。在某些情况下,每种方式都有其优势。在这篇文章中,我们将研究所有的可能性。

例如,假设我们有一个可用的30年期固定利率住房抵押贷款产品表,这些产品在利率、点数(作为“买低”利率的一种方式添加到请求的金额)和固定费用方面有所不同。您可以在网络上找到此数据,费率每天都在变化。在我们的决策服务中,我们希望允许用户找到特定贷方的当前利率,此外还可以找到该贷方的每月还款额,这取决于请求的贷款金额。查找贷方的当前利率是对未经修改的外部数据的基本查找。使用该贷方查找每月付款需要额外计算。让我们看一下一些不同的建模方法。

我们可以从贷方和利率表开始,这些表格要么是输入的,要么是通过网络抓取捕获的。在Excel中,它看起来像这样:

查找1.png

我们在Together建模器中自定义一银行利率-Structure列数据类型,如下所示:

查找2.png


数据类型的每一行都具有与表列匹配的字段。下面是对此进行建模的一种方案,使用查找未修改的外部数据,然后将其他逻辑应用于返回值。

查找3.png

我们将输入数据银行利率设置银行利率自定义类型,并查找我的利率-适用于输入数据我的借款人的利率。查找决策我的利率使用筛选表达式。数据表筛选器通常具有以下格式

<table>[<Booleanexpressionoftablecolumns>]

其中,用方括号括起来的筛选器包含布尔表达式。这里的表是银行利率,布尔表达式是借款人名称=我的借款人。换言之,选择列借款人名称与输入数据我的借款人匹配的行。

筛选器始终返回一个列表,即使它只包含一个项目。为了从此列表中提取项目,我们使用第二种形式的过滤器,其中方括号括起一个整数:

<list>[<integerexpression>]

在本例中,我们知道我们的数据表对每个贷方只有一个条目,因此我们可以通过附加过滤器[1]从第一个过滤器中提取所选行。结果不再是列表,而是表中的单行,键入银行利率

查找5.png

我的付款额决策使用贷款摊销公式的BKM,这是一个复杂的算术表达式,涉及贷款本金(p)、利率(r)和付款次数(n),在本例中为360。

查找6.png

决策我的付款额使用查找结果我的费率调用此BKM。输入数据贷款金额只是借款人请求的金额,但贷款摊销公式(参数p)中使用的贷款本金还包括贷款人的积分和费用。由于银行数据类型中的点数利率表示为百分比,因此我们需要除以100才能获得BKM公式中使用的十进制值。

查找7.png

当我们与我的贷方“工商银行”一起运行它并贷款金额为400,000元时,我们得到了此处显示的结果。

查找8.png

这是一种方法。另一种方法是使用其他列(例如给定贷款金额的每月还款额)扩充外部数据表,然后对此扩充的数据表执行查找。在这种情况下,数据表是一个决策,而不是输入数据。

查找9.png

此处,扩充的表“按银行付款金额”根据输入数据贷款金额增加了一个列“付款”。向表中添加列涉及对表行的迭代,每次迭代都会生成一个新行,包括其他列。过去,我通常使用没有最终结果框的上下文BKM来生成每个新行。但实际上,将文字表达式与contextput()函数一起使用更简单,因为生成行不需要BKM,尽管我们仍然需要贷款摊销公式。对用户来说更简单,但由此产生的字面表达确实令人生畏,所以我将向您展示另一种盒装表达式,将其分解为更简单的部分。

contextput()与参数context、keys和value一起将组件(由键命名)附加到现有结构(context)中,并赋值。如果键包含上下文的现有组件,则值将覆盖以前的值。这里的键是新的列名称“付款金额”,值是使用BKM贷款摊销公式计算的。因此,作为一个单一的文字表达,银行付款金额如下所示:

查找10.png

在这里,我们使用了BKM的文字调用而不是盒装调用,并应用了decimal()函数来对结果进行舍入。

或者,我们可以使用迭代器盒装表达式而不是文字for..in..return运算符和调用内置函数decimal()和contextput()以及BKM的盒装表达式。使用FEEL内置函数,您通常使用文本调用,但您也可以使用盒装调用。

查找11.png

现在,我的付款是对扩充数据表银行付款金额的简单查找,附加[1]筛选器以提取该行,然后附加.付款金额以提取该行的付款值。

查找12.png

当我们运行它时,我们得到工商银行的相同结果,贷款金额为400,000元:

查找13.png

扩充的数据表现在允许在查询中具有更大的灵活性。例如,您可以使用筛选表达式来查找每月还款额最低的贷款产品,而不是查找特定贷方的付款:

银行付款金额[付款金额=min(银行付款金额.付款金额)]

它返回一条记录工商银行。当然,您也可以使用筛选器查询来选择符合您条件的记录数量。例如

银行付款金额[付款金额<2650]

将返回工商银行中国银行民生银行华夏银行的记录。

银行付款金额[点数=0and费用=0]

将返回零点/零费用贷款产品的记录:建设银行中信银行浦发银行

这两种方法都需要在执行时提交数据表银行利率。我们的示例表很小,但在实际项目中,数据表可能非常大,有数千行。对于在建模环境中进行测试来说,这更像是一个问题,因为在部署的服务中,数据以编程方式以JSON或XML的形式提交。但为了简化测试,有几种方法可以避免每次都输入数据表。

您可以使用关系盒装表达式使数据表成为零输入决策。在Together平台上,您可以使用从Excel导入数据。要运行此操作,您只需要输入我的借款人和贷款金额的值。您也可以在生产环境中执行此操作,但请记住,对于零输入决策,如果不对模型进行版本控制,则无法更改银行利率值。

查找14.png

或者,您可以将银行利率保留为输入数据,但将其绑定到云数据存储。通过管理界面,您可以将Excel表上传到数据存储中,并在数据存储中将其保留为FEEL表。因此,在决策模型中,无需在执行时提交表数据,并且可以定期更新银行利率值,而无需对模型进行版本控制。DRD中输入数据上的图标表示其值已锁定到数据存储。

使用筛选表达式的查找表是您将在DMN中始终使用的基本模式。

下一篇DMN123
文章分类: DMN建模
分享到:
精选文章
公众号
关于我们
联系方式
让您的业务更自动化、智能化!
联系邮箱:   zhangy@jee-soft.cn       wangyl@jee-soft.cn
185 1521 8668
183 3562 2627
联系电话: