如何防止流口水引擎在入口点数据上循环

问题描述

我正在使用 drools 来对流式交易数据发出警报。 drools 引擎是 STREAM 和 ACTIVE 模式。我还使用入口点 (OM-TRANS) 将数据传输到规则引擎。 我写了一个简单的规则来测试引擎的行为。我得到了一些结果,但我不理解它们,它们不是我所期望的。

这是第一个简单的规则:

rule "My rule"
    no-loop true
    when
        $transaction: TransactionOmDto($msisdn: msisdn) from entry-point "OM-TRANS"
    then
        System.out.println("------------ an alarm on "+$msisdn+" ----------");
    end

这些是我测试后得到的结果:

  1. 来自 msisdn 的交易msisdn_1

------------ an alarm on msisdn_1 ----------

  1. 再次来自 msisdn msisdn_1 的交易:

------------ an alarm on msisdn_1 ----------

  1. 来自 msisdn 的交易msisdn_2

------------ an alarm on msisdn_2 ----------

  1. 再次来自 msisdn msisdn_2 的交易:

------------ an alarm on msisdn_2 ----------

  1. 来自 msisdn 的交易msisdn_3

------------ an alarm on msisdn_3 ----------

这是规则的第二个版本:

rule "My rule"
    no-loop true
    when
        $transaction: TransactionOmDto($msisdn: msisdn) from entry-point "OM-TRANS"
        $datasTransaction: List() from collect(TransactionOmDto(msisdn == $msisdn) from entry-point "OM-TRANS")
    then
        System.out.println("------------ an alarm on "+$msisdn+",total Transaction: "+$datasTransaction.size()+" ----------");
    end

我得到了以下结果和我期望的结果:

  1. 来自 msisdn 的交易msisdn_1

------------ an alarm on msisdn_1,total Transaction: 1 ---------- (这是预期的)

  1. 再次来自 msisdn msisdn_1 的交易:
------------ an alarm on msisdn_1,total Transaction: 2 ----------
------------ an alarm on msisdn_1,total Transaction: 2 ----------

我期望的是:单行------------ msisdn_1 上的警报,总交易:2 -------- --

  1. 来自 msisdn 的交易msisdn_2

------------ an alarm on msisdn_2,total Transaction: 1 ----------(如预期)

  1. 再次来自 msisdn msisdn_2 的交易:
------------ an alarm on msisdn_2,total Transaction: 2 ----------
------------ an alarm on msisdn_2,total Transaction: 2 ----------

我期望的是:单行------------ msisdn_2 上的警报,总交易:2 -------- --

  1. 来自 msisdn 的交易msisdn_3

------------ an alarm on msisdn_3,total Transaction: 1 ---------- (这是预期的)

  1. 再次来自 msisdn msisdn_3 的交易:
------------ an alarm on msisdn_3,total Transaction: 2 ----------
------------ an alarm on msisdn_3,total Transaction: 2 ----------

我期望的是:单行------------ msisdn_3 上的警报,总交易:2 -------- --

  1. 再次来自 msisdn msisdn_3 的交易:
------------ an alarm on msisdn_3,total Transaction: 3 ----------
------------ an alarm on msisdn_3,total Transaction: 3 ----------

我期望的是:单行------------ msisdn_3 上的警报,总交易:3 -------- --

有人可以向我解释为什么我得到这些结果吗? 有可能得到我所期望的吗? 谢谢你。

解决方法

因为您的事件仅在 24 小时内到期,所以较旧的事件确实会参与规则逻辑。
通常这可以通过滑动长度窗口来修复

 over window:length(1) from entry-point "OM-TRANS"

完整片段

rule "My rule2"
no-loop true
when
    $transaction: TransactionOmDto($msisdn: msisdn) over window:length(1) from entry-point "OM-TRANS"
    $datasTransaction: List() from collect(TransactionOmDto(msisdn == $msisdn) from entry-point "OM-TRANS")
then
    System.out.println("------------ an alarm on "+$msisdn+",total Transaction: "+$datasTransaction.size()+" ----------");
end

输出

------------ an alarm on msisdn_1,total Transaction: 1 ----------
------------ an alarm on msisdn_1,total Transaction: 2 ----------
------------ an alarm on msisdn_1,total Transaction: 3 ----------

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...