【问题标题】:Per which data object should I create my Drools/Kie session?我应该根据哪个数据对象创建我的 Drools/Kie 会话?
【发布时间】:2017-02-07 21:12:30
【问题描述】:

我有以下 POJO:

public class Transaction {

    @Id
    private long id;

    private String organisationId;

    private String resposibleName;

    private DateTime transactionTime;

    private BigDecimal amount;

    ...

}

我想应用我的规则。例如,一个示例规则可能是关于它的数量:

rule "SampleRule"
    when
        $transaction : Transaction( amount > 10)
    then
        $transaction.setStatus(Status.INVALID);
end

我还想应用一些更复杂的规则,例如:

  1. WHEN上周内同一organisationId的交易金额字段之和(基于transactionTime)大于xTHEN$transaction.setStatus(Status.INVALID);
  2. WHEN 有一个过去的交易,responsibleName 与正在评估的当前交易相同,但 organisationId 与当前交易不同,THEN $transaction.setStatus(Status.INVALID);

当对 RESTful 端点进行查询时:

  1. 我正在创建一个新的KieSession
  2. 向会话中添加单个 Transaction 对象,
  3. 添加更多可能与当前具有不同 POJO 的事务对象相关的事务对象(例如,说 PastTransactionTransaction 具有相同字段的确切副本,我正在添加由相同 organisationId 进行的多个事务使用PastTransaction POJO,这样我就可以在这些字段上累积金额字段,同时能够在我的Transaction 对象上应用更多基本规则。
  4. 以同样的方式,我将由同一个responsibleName 进行的所有事务添加到ResponsibleNameTransaction POJO,并编写一条规则来检查其中是否有任何不等于我的单个Transaction KieSession 中的对象。

我想知道是否有更简单/更优化的方法来实现我一直在做的事情,并根据我为哪个实体形成KieSessions 进行优化。我已经向我的Transaction POJO 编写方法并在规则执行中命中数据库(例如,编写一个返回列表的方法getAllTransactionsByTheResponsibleName,然后检查是否有一个具有不同organisationId 的对象)。以同样的方式,我可以将相关事务作为列表添加到KieSession,然后在规则中查询该列表,这至少可以避免我使用不同名称的相同 POJO。

更新:

基于 cmets 进一步阐述,在工作内存中保留大约 10 亿个Transactions(所有事务的会话)是否可行?或者,我可以将每个负责人/组织的事务放入KieSession(每个负责人/组织的会话)。那么当会话中有多个事务时(例如$transaction.setStatus(Status.INVALID); 当#1 为真,$transaction 是一个目前正在评估)?

【问题讨论】:

  • 如果您有一个事务能够根据#1 选择其他事务并根据#2 选择第二组事务,则不再需要规则:您可以从这两个中计算所需的结果收藏品。 -- 通常,所有事务都被输入到工作内存中——甚至可能是实时的——并且规则根据#1 和#2 查找事务和集合,并动态评估所有内容。当然,这取决于您需要回到多远的时间才能根据 #2 检测冲突。 #1 有一周的限制,所以你应该知道会发生什么。
  • 您的意思是基于 organizationId 和 responsibeName 返回过去交易的 Transaction 方法吗?你说我不再需要规则是什么意思?我使用 Drools 的原因有很多,其中之一是非技术人员能够通过工作台编辑规则。另外,我每天有 1000 万笔交易,这可能使得将所有交易一直保存在内存中是不可行的。
  • 如果从数据库中获取相关数据集(事务)取决于规则(正如您的“更复杂”规则所暗示的那样),您将无法让您的非技术人员编写此只是通过工作台。 - 考虑#1:当您获取时,您不妨添加并检查;一旦beyonx你可以停下来。考虑#2:当您遇到第一个结果为肯定结果时,获取所有具有相同责任名称的 T 是否有意义? -- 如果数据在 WM 中,则规则可以很好地工作,并且不需要使用不同的类名来编写此类规则。
  • @laune 我明白了。然后问题变成了当会话中有超过 1 个时,我如何设置字段/对正在评估的最新事务应用一些规则。更新了我的问题。感谢您的帮助,谢谢!

标签: java drools rule-engine


【解决方案1】:

可能无法让您的非技术人员完全在无人帮助的情况下嬉戏。全面讨论您可能需要添加的内容需要完全了解所有规则,而我没有。但是,即使有数十亿个事务通过您的工作内存,您的 Q 中的 #1 和 #2 也可以处理。

用例 1:检查某个时间范围内每个帐户的阈值可以通过为每个帐户保留一个具有 n 每日总和的辅助事实(“AccountSums”)来完成。对于任何新的交易,要么更新最后一个总和,要么“移位”总和加上 0 个总和并设置最后一个总和,或者创建新的 AccountSum;维护最后 n 个总和 - 技术人员可以仅根据 AccountSums(或结合(最后)匹配的交易)来编写支票。

rule "check 7 days limit"
when
    $t: Transaction( $orgId: organisationId,
                     $transT: transactionTime,
                     amount > 0, status == Status.VALID )
    AccountSums( organisationId == $orgId,
                 lastTransactionTime == $transT,
                 runningWeeklySum > 1000000 )
then
    modify( $t ){ setStatus( Status.INVALId ) }
end

rule "create AccountSums"
when
    $t: Transaction( $orgId: organisationId,
                     amount > 0 )
    not AccountSums( organisationId == $orgId )
then
    insert( new AccountSums( $orgId ) );
end 

您至少需要一个额外的规则来“转移”总和等。

用例 2:维护一个辅助事实(“NameId”),其中包含负责名称和组织 ID 的实例(或包含 Map 的单个实例。)如果另一个事务到达,则创建一个新的 NameId(或 Map 条目) , 或比较相等和不相等的 Id。

如果您的数据量如您所指,则必须精简历史记录。让研究人员编写简单的评估规则是可能的,但按照我在这里概述的思路设计规则模式至少是为了压缩元数据,而不是你可以留给麻瓜的东西。

【讨论】:

  • 谢谢,能否请您添加一个示例规则,以检查新添加的交易金额,例如?当向我的 API 中的某个端点发出请求时,我会将其添加到会话中,并希望仅在其字段上应用一个非常基本的规则,并在其上设置一个字段。谢谢!
  • 喜欢this?
  • 我已经草拟了几条规则。没有保证。这需要一些谨慎w.r.t。时间,何时限制“陈旧”的 AccountSums 和其他详细信息。但你应该明白...
  • 对不起,我应该更清楚。我有一个端点,我在正文中使用单个事务发出请求,我必须返回该特定事务的状态。如果我没记错的话,您编写的方法设置了验证规则的所有事务的状态。我真的需要应用规则后需要返回的特定交易的状态。
  • 你错了。在触发结束时,所有规则都已处理(一个)事务,是否设置为无效。然后,您将其从会话中删除,然后生活继续。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多