drools 复杂事件处理Complex Event Processing

1 Drools Fusion

Drools Fusion是负责将事件处理功能添加到平台的模块。

2 事件语义

event是呈现出几个显着特点的fact:

  • 通常是不可变的:因为,通过前面讨论的定义,事件是应用程序域中状态变化的记录,即已经发生的事情的记录,并且过去不能“改变”,事件是不可变的。此约束是开发多个优化和事件生命周期规范的重要要求。这并不意味着表示对象的Java对象必须是不可变的。恰恰相反,Drools引擎不会强制执行对象模型的不变性,因为规则的最常见用例之一是事件数据丰富。
  • 强时间约束:涉及事件的规则通常需要多个事件的相关性,特别是时间相关性,其中事件据说相对于其他事件在某个时间点发生。
  • 托管生命周期:由于其不可变性和时间限制,事件通常仅在有限的时间窗口内与其他事件和事实匹配,从而使Drools引擎可以自动管理事件的生命周期。换句话说,一个事件被插入到工作存储器中,Drools引擎可以找出事件何时不能与其他事实匹配并自动删除它,释放其相关资源。

  • 使用滑动窗口:由于所有事件都有与之关联的时间戳,因此可以在它们上面定义和使用滑动窗口,从而允许在一段时间内创建值聚合规则。示例:超过60分钟的事件值的平均值。

Drools支持使用语义声明和使用事件:时间点事件和基于时间间隔的事件。

3 事件处理模式

规则引擎通常具有处理数据和规则的公知方式,并向应用程序提供结果。此外,关于如何向规则引擎呈现事实的要求并不多,特别是因为通常,处理本身与时间无关。对于大多数情况来说,这是一个很好的假设,但对所有情景都不是。当要求包括实时或近实时事件的处理时,时间成为推理过程的重要变量。以下部分将解释时间对规则推理的影响以及Drools为推理过程提供的两种模式。

3.1 cloud模式

CLOUD处理模式是默认处理模式。规则引擎的用户熟悉此模式,因为它的行为与任何纯正向链接规则引擎完全相同,包括以前版本的Drools。

在CLOUD模式下运行时,Drools引擎会查看工作内存中的所有事实,如果它们是常规事实或事件,则无关紧要。虽然事件像往常一样有时间戳,但没有时间流动的概念。换句话说,尽管Drools引擎知道某个特定事件是在2009年1月1日09:35:40.767创建的,但Drools引擎无法确定事件的“老”程度,因为没有“现在”的概念。

在这种模式下,Drools引擎将应用其通常的多对多模式匹配算法,使用规则约束来查找匹配的元组,像往常一样激活和触发规则。

此模式不会对事实施加任何其他要求。例如:

  • 没有时间概念。没有要求时钟同步。

  • 事件排序没有要求。Drools引擎将事件视为无序云,Drools引擎尝试匹配规则。

另一方面,由于没有要求,也没有一些好处。例如,在CLOUD模式下,不可能使用滑动窗口,因为滑动窗口基于“现在”的概念,并且在CLOUD模式中没有“现在”的概念。

由于事件没有排序要求,因此Drools引擎无法确定事件何时不再匹配,因此事件没有自动生命周期管理。即,应用程序必须在不再需要时显式删除事件,就像应用程序使用常规事实一样。

云模式是Drools的默认执行模式,但无论如何,与Drools中的任何其他配置一样,可以通过设置系统属性,使用配置属性文件或使用API​​来更改此行为。相应的属性是:

KieBaseConfiguration config = KieServices.Factory.get().newKieBaseConfiguration();
config.setOption( EventProcessingOption.CLOUD );

等价的属性是:

drools.eventProcessingMode = cloud

3.2 Stream 模式

当应用程序需要处理事件流时,STREAM处理模式是选择的模式。它为常规处理添加了一些常见要求,但启用了许多使流事件处理更加简单的功能。

使用STREAM模式的主要要求是:

  • 每个流中的事件必须按时间排序。即,在给定流内,首先发生的事件必须首先插入Drools引擎。

  • Drools引擎将通过使用会话时钟强制流之间的同步,因此,尽管应用程序不需要在流之间强制执行时间排序,但使用非时间同步流可能会导致一些意外结果。

鉴于满足上述要求,应用程序可以使用以下API启用STREAM模式:

KieBaseConfiguration config = KieServices.Factory.get().newKieBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );

或者,等效属性:

drools.eventProcessingMode = stream

当使用STREAM时,Drools引擎知道时间流的概念和“现在”的概念,即Drools引擎根据从会话时钟读取的当前时间戳了解旧事件的大小。这一特性使Drools引擎能够为应用程序提供以下附加功能:

  • 滑动窗口支撑

  • 自动事件生命周期管理

  • 使用否定模式时自动规则延迟

以下各节将介绍所有这些功能。

3.2.1 会话时钟在流模式下的作用

在CLOUD模式下运行Drools引擎时,会话时钟仅用于为没有先前定义的时间戳属性的到达事件添加时间戳。

在STREAM模式下,会话时钟负责保持当前时间戳,并且基于此,Drools引擎会对事件的老化进行所有时间计算,同步来自多个源的流,安排将来的任务等等。

3.2.2 流模式中的负匹配

与CLOUD模式相比,STREAM模式下的负匹配表现不同。在CLOUD模式下,Drools引擎假定事先知道所有事实和事件(没有时间流的概念),因此,立即评估负模式。

在STREAM模式下运行时,具有时间约束的负匹配可能需要Drools引擎在激活规则之前等待一段时间。时间段由Drools引擎自动计算,用户不需要使用任何技巧来获得所需的结果。

示例151.在匹配时立即激活的规则

rule "Sound the alarm"
when
    $f : FireDetected( )
    not( SprinklerActivated( ) )
then
    // sound the alarm
end

上述规则没有时间限制,需要延迟规则,因此,规则立即激活。另一方面,以下规则必须在激活前等待10秒,因为喷头可能需要10秒才能激活:

示例152.由于时间约束而自动延迟激活的规则

rule "Sound the alarm"
when
    $f : FireDetected( )
    not( SprinklerActivated( this after[0s,10s] $f ) )
then
    // sound the alarm
end

这种行为允许Drools引擎在同时处理负模式和时间约束时保持一致性。以上内容与编写如下规则相同,但不会给用户带来计算和显式写入适当持续时间参数的负担:

例153.具有显式持续时间参数的相同规则

rule "Sound the alarm"
    duration( 10s )
when
    $f : FireDetected( )
    not( SprinklerActivated( this after[0s,10s] $f ) )
then
    // sound the alarm
end

 以下规则要求每10秒至少有一次“心跳”事件,如果不是规则触发的话。此规则中的特殊情况是我们在第一个模式和负模式中使用相同类型的对象。负模式具有在发射之前在0到10秒之间等待的时间约束,并且它排除了绑定到$ h的心跳。排除绑定的心跳是很重要的,因为时间约束[0s,...]不会自己排除绑定事件$ h再次匹配,从而阻止规则触发。

rule "Sound the alarm"
when
    $h: Heartbeat( ) from entry-point "MonitoringStream"
    not( Heartbeat( this != $h, this after[0s,10s] $h ) from entry-point "MonitoringStream" )
then
    // Sound the alarm
end

4 Session Clock 会话时钟

随着时间推移需要一个参考时钟。仅举一个例子,如果规则超过过去60分钟内给定股票的平均价格,那么Drools引擎如何知道过去60分钟内发生的股票价格变化以计算平均值?明显的反应是:通过比较事件的时间戳和“当前时间”。Drools引擎如何知道现在几点了?显然,通过查询会话时钟。

会话时钟实现了策略模式,允许Drools引擎插入和使用不同类型的时钟。这非常重要,因为Drools引擎可能运行在可能需要不同时钟实现的不同场景的元素中。仅举几例:

  • 规则测试:测试总是需要受控环境,当测试包含具有时间约束的规则时,不仅需要控制输入规则和事实,还需要控制时间流。

  • 定期执行:通常,在生产中运行规则时,应用程序将需要一个实时时钟,允许Drools引擎立即对时间进程作出反应。

  • 特殊环境:特定环境可能对时间控制有特定要求。群集环境可能需要通过心跳进行时钟同步,或者JEE环境可能需要使用AppServer提供的时钟等。

  • 规则重放或模拟:为了重放场景或模拟场景,应用程序还必须控制时间流。

4.1 可用的时钟

Drools 5提供开箱即用的2个时钟实现。基于系统时钟的默认实时时钟和由应用程序控制的可选伪时钟。

4.1.1 实时时钟

默认情况下,Drools使用实时时钟实现,在内部使用系统时钟来确定当前时间戳。

要显式配置Drools引擎以使用实时时钟,只需将会话配置参数设置为实时:

KieSessionConfiguration config = KieServices.Factory.get()
                                     .newKieSessionConfiguration();
 config.setOption( ClockTypeOption.get("realtime") );

4.1.2 伪时钟

Drools还提供开箱即用的时钟实现,该时钟由称为伪时钟的应用程序控制。这个时钟对于单元测试时态规则特别有用,因为它可以由应用程序控制,因此结果变得确定。

要配置伪会话时钟,请执行以下操作:

KieSessionConfiguration config = KieServices.Factory.get()
                                            .newKieSessionConfiguration(); 
config.setOption( ClockTypeOption.get("pseudo") );

作为如何控制伪会话时钟的示例:

KieSessionConfiguration config = KieServices.Factory.get()
                                            .newKieSessionConfiguration();
conf.setOption( ClockTypeOption.get( "pseudo" ) );
KieSession session = kbase.newKieSession( conf, null );

SessionPseudoClock clock = session.getSessionClock();

// then, while inserting facts, advance the clock as necessary:
FactHandle handle1 = session.insert( tick1 );
clock.advanceTime( 10, TimeUnit.SECONDS );
FactHandle handle2 = session.insert( tick2 );
clock.advanceTime( 30, TimeUnit.SECONDS );
FactHandle handle3 = session.insert( tick3 );

5 Sliding Windows

滑动窗口是一种通过定义不断移动的窗口来定义感兴趣的事件的方法。两种最常见的滑动窗口实现类型是基于时间的窗口和基于长度的窗口。

接下来的部分将详细介绍它们。

只有在STREAM模式下运行Drools引擎时才能使用滑动窗口。有关STREAM模式如何工作的详细信息,请查看“事件处理模式”部分。

滑动窗口立即开始匹配并且定义滑动窗口并不意味着规则必须等待滑动窗口“满”才能匹配。例如,计算窗口上事件属性平均值的规则:length(10)将立即开始计算平均值,并且对于无事件将从0(零)开始,并在事件到达时更新平均值逐一。

5.1 滑动时间Windows

滑动时间Windows允许用户编写仅匹配最后X个时间单元中发生的事件的规则。

例如,如果用户只想考虑最近2分钟内发生的Stock Ticks,那么模式将如下所示:

StockTick() over window:time( 2m )

Drools使用“over”关键字将窗口与模式相关联。

在一个更详细的例子中,如果用户想要在传感器读取的最后10分钟内的平均温度高于阈值时发出警报,则规则如下:

rule "Sound the alarm in case temperature rises above threshold"
when
    TemperatureThreshold( $max : max )
    Number( doubleValue > $max ) from accumulate(
        SensorReading( $temp : temperature ) over window:time( 10m ),
        average( $temp ) )
then
    // sound the alarm
end

Drools引擎将自动忽略任何超过10分钟的SensorReading并保持计算的平均值一致。

请注意,在计算事件在到期之前保留在工作内存中的时间间隔时会考虑基于时间的窗口,但是从滑动窗口掉落的事件本身并不意味着事件将从工作内存中丢弃,因为可能是依赖于该事件的其他规则。仅当没有其他规则依赖于该事件并且满足该事件类型的到期策略时,Drools引擎才会丢弃事件。

5.2 滑动长度Windows

Sliding Length Windows的工作方式与Time Windows相同,但会根据事件插入会话的顺序而不是时间流来考虑事件。

例如,如果用户想要仅考虑最后10个RHT股票定时器,与它们的年龄无关,则模式将如下所示:

StockTick( company == "RHT" ) over window:length( 10 )

如您所见,该模式类似于上一节中介绍的模式,但不是使用window:time来定义滑动窗口,而是使用window:length。

使用与上一节中类似的示例,如果用户想要在传感器的最后100个读数的平均温度高于阈值的情况下发出警报,则规则将如下所示:

rule "Sound the alarm in case temperature rises above threshold"
when
    TemperatureThreshold( $max : max )
    Number( doubleValue > $max ) from accumulate(
        SensorReading( $temp : temperature ) over window:length( 100 ),
        average( $temp ) )
then
    // sound the alarm
end

Drools引擎仅考虑最后100个读数来计算平均温度。

请注意,从基于长度的窗口中删除不是会话中事件到期的标准。Drools引擎在计算该窗口时忽略窗口上掉落的事件,但不会仅基于该条件从会话中删除事件,因为可能存在依赖于该事件的其他规则。

请注意,基于长度的窗口不会为会话中的事件过期定义时间约束,并且Drools引擎不会考虑它们。如果事件没有定义时间约束的其他规则且没有明确的到期策略,则Drools引擎将无限期地将它们保留在会话中。

使用滑动窗口时,在考虑窗口之前评估alpha约束,但之后会评估beta(连接)约束。当涉及时间窗口时,这通常没有区别,但是在使用长度窗口时这很重要。例如这种模式:

StockTick( company == "RHT" ) over window:length( 10 )

定义一个(最多)10个“RHT”公司的StockTicks的窗口,也可以在working memory中定义company:

$s : String()
StockTick( company == $s ) over window:length( 10 )

5.3 Window Declaration 窗口声明

Drools引擎还支持Windows的声明。这促进了应用于窗口的过滤器与应用于窗口结果的约束之间的明确区分。它还允许在多个规则之间轻松重用窗口。

另一个好处是Drools引擎中基本窗口支持的新实现,提高了使用滑动窗口的规则的整体性能。

声明窗口的简化EBNF是:

windowDeclaration := DECLARE WINDOW ID annotation* lhsPatternBind END

例如,一个仅包含给定来源的最后10个股票价格的窗口可以定义为:

declare window Ticks
    StockTick( source == "NYSE" )
        over window:length( 10 )
        from entry-point STStream
end

然后,规则可以使用此声明的窗口,将其用作FROM的源,如下所示:

rule "RHT ticks in the window"
    when
        accumulate( StockTick( company == "RHT" ) from window Ticks,
                    $cnt : count(1) )
    then
        // there has been $cnt RHT ticks over the last 10 ticks
end

请注意,此示例还演示了窗口声明如何允许分隔应用于窗口的约束(只有具有“NYSE”作为源的StockTicks是窗口中包含的10个事件之一)和应用于窗口结果的约束(在最后一个中)选择具有“NYSE”作为源的仅10个具有等于“RHT”的公司的事件。

6 Streams支持

大多数CEP用例必须处理事件流。流可以以各种形式提供给应用程序,从JMS队列到平面文本文件,从数据库表到原始套接字,甚至通过Web服务调用。无论如何,这些流共享一组共同的特征:

  • 流中的事件按时间戳排序。时间戳可能对不同的流具有不同的语义,但它们始终在内部排序。

  • 事件量通常很高。

  • 原子事件本身很少有用。通常意义是从流中的多个事件与其他来源之间的相关性中提取的。

  • 流可以是同类的,即包含单一类型的事件,或者是异构的,即包含多种类型的事件。

在Drools中,来自一个entry point(流)的事实可以与来自任何其他entry point或事件的事实一起与来自工作记忆的事实相结合。虽然,它们从不混合,即它们永远不会失去对它们进入Drools引擎的entry point的引用。这很重要,因为可能有相同类型的事实通过几个entry point进入Drools引擎,但是例如通过entry pointA插入Drools引擎的一个事实将永远不会与entry pointB的模式匹配.

6.1 声明和使用入口点

Drools中的entry point是通过在规则中直接使用它们来隐式声明的。即,引用规则中的entry point将使Drools引擎在编译时识别并创建适当的内部结构以支持该入口点。

因此,举例来说,让我们想象一下银行应用程序,其中事务被送入来自流的系统。其中一个流包含ATM机中执行的所有事务。因此,如果其中一条规则说明:当且仅当帐户余额超过请求的提款金额时才授权提款,规则如下:

rule "authorize withdraw"
when
    WithdrawRequest( $ai : accountId, $am : amount ) from entry-point "ATM Stream"
    CheckingAccount( accountId == $ai, balance > $am )
then
    // authorize withdraw
end

在前面的示例中,Drools引擎编译器将识别该模式与入口点“ATM Stream”相关联,并且将为规则库创建所有必要的结构以支持“ATM Stream”,并且仅匹配来自“ATM流”。在前面的示例中,规则还将来自流的事件与来自主工作内存(CheckingAccount)的事实相结合。

现在,让我们想象一下第二条规则,规定每个2美元的费用必须适用于在银行分行提出取款请求的任何账户:

rule "apply fee on withdraws on branches"
when
    WithdrawRequest( $ai : accountId, processed == true ) from entry-point "Branch Stream"
    CheckingAccount( accountId == $ai )
then
    // apply a $2 fee on the account
end

先前的规则将匹配与第一个规则(WithdrawRequest)完全相同类型的事件,但是来自两个不同的流,因此插入“ATM流”的事件将永远不会针对第二个规则上的模式进行评估,因为规则指出它只对来自“分支流”的模式感兴趣。

因此,入口点除了作为流的适当抽象之外,还是一种在工作记忆中确定事实的方法,并且是减少交叉产品爆炸的有用工具。但那是另一个时间的主题。

将fact插入入口点同样简单。不是将事件直接插入工作内存,而是将它们插入入口点,如下例所示:

// create your rulebase and your session as usual
KieSession session = ...

// get a reference to the entry point
EntryPoint atmStream = session.getEntryPoint( "ATM Stream" );

// and start inserting your facts into the entry point
atmStream.insert( aWithdrawRequest );

前面的示例显示了如何手动将fact插入到给定的入口点。虽然通常,应用程序将使用众多适配器中的一个将流端点(如JMS队列)直接插入Drools引擎入口点,而无需手动编写插入代码。Drools管道API有几个适配器和帮助程序,以及如何执行此操作的示例。

7 事件的内存管理Memory Management for Events

仅在STREAM模式下运行Drools引擎时才会执行事件的自动内存管理。有关STREAM模式如何工作的详细信息,请查看“事件处理模式”部分。

在STREAM模式下运行Drools引擎的一个好处是,Drools引擎可以检测事件何时由于其时间限制而无法再与任何规则匹配。当发生这种情况时,Drools引擎可以安全地从会话中删除事件而没有副作用,并释放该事件使用的任何资源。

Drools引擎基本上有两种方法来计算给定事件的匹配窗口:

  • 明确地,使用过期策略

  • 隐含地,分析事件的时间约束

7.1  显示到期偏移量

允许Drools引擎计算给定事件类型的感兴趣窗口的第一种方法是通过显式设置它。为此,只需使用declare语句并为事实类型定义到期:

declare StockTick
    @expires( 30m )
end

上面的示例声明了StockTick事件的到期偏移量为30分钟。在此之后,假设没有规则需要该事件,Drools引擎将过期并自动从会话中删除该事件。给定事件类型的显式到期策略将覆盖该相同类型的任何推断的到期偏移量。

7.2 推断的到期偏移量

通过分析规则中的时间约束,Drools引擎计算给定事件的到期偏移的另一种方式是隐含的。例如,给出以下规则:

rule "correlate orders"
when
    $bo : BuyOrderEvent( $id : id )
    $ae : AckEvent( id == $id, this after[0,10s] $bo )
then
    // do something
end

分析上述规则,Drools引擎会自动计算出每当BuyOrderEvent匹配时,它需要存储最多10秒钟以等待匹配AckEvent。因此,BuyOrderEvent的隐式到期偏移量将为10秒。另一方面,AckEvent只能匹配现有的BuyOrderEvent,因此它的到期偏移量将为零秒。Drools引擎将对整个规则库进行分析,并找到每种事件类型的偏移量。

给定事件类型的显式到期策略将覆盖该相同类型的任何推断的到期偏移量。

8 时间推理

时间推理是任何CEP系统的另一个要求。如前所述,事件的一个显着特征是它们强烈的时间关系。

时间推理是一个广泛的研究领域,从时间模态逻辑的根源到其在商业系统中更实际的应用。撰写了数百篇论文和论文,并针对多种应用描述了方法。Drools再次采用基于多种来源的实用且简单的方法,但特别值得注意以下论文:

  • [ALLEN81] Allen,JF。基于区间的时间知识表示。1981年。

  • [ALLEN83] Allen,JF。保持有关时间间隔的知识。1983年。

  • [BENNE00] Bennet,Brandon和Galton,Antony P .. 时间和事件的统一语义。2005年。

  • [YONEK05] Yoneki,Eiko和Bacon,Jean。混合网络环境中时间和空间事件关联的统一语义。2005年。

Drools实现Allen描述的基于区间的时间事件语义,并将时间点事件表示为基于区间的均衡,持续时间为0(零)

对于所有时间运算符间隔,“ ”(星号)符号用于表示正无穷大,“ - ”(负星号)用于表示负无穷大

8.1 时间运算符

Drools实现了Allen定义的所有13个运算符以及它们的逻辑补码(否定)。本节详细介绍了每个运算符及其参数。

8.1.1 after

例如:

当且仅当$ eventB结束的时间与$ eventA开始的时间之间的时间距离在(3分钟和30秒)和(4分钟)之间时,前一模式将匹配。

$eventA : EventA( this after[ 3m30s, 4m ] $eventB )

换一种说法:

3m30s <= $eventA.startTimestamp - $eventB.endTimeStamp <= 4m

after运算符的时间距离间隔是可选的:

  • 如果定义了两个值(如下例所示),则间隔从第一个值开始,在第二个值上结束。

  • 如果只定义了一个值,则间隔从值开始,并在正无穷大处结束。

  • 如果未定义任何值,则假定初始值为1ms,最终值为正无穷大。

after可以定义负值,但是drools会自动将小的值放到前面,例如下面这两种写法实现的效果是一样的:

$eventA : EventA( this after[ -3m30s, -2m ] $eventB )
$eventA : EventA( this after[ -2m, -3m30s ] $eventB )

值得注意的是:after ,before and coincides操作符可以在events,java.util.Date,long(interpreted as timestamps since epoch)之间进行结合使用。

EventA( this after $someDate )

8.1.2 before 结合after字面意义理解

8.1.3 Coincides(重合)

当两个事件同时发生时,重合评估器将两个事件和匹配相关联。可选地,评估器接受事件的开始和结束时间戳之间的距离的阈值。

让我们看一个例子:

$eventA : EventA( this coincides $eventB )

当且仅当$ eventA和$ eventB的开始时间戳相同且$ eventA和$ eventB的结束时间戳也相同时,前一个模式才匹配。

可选地,该运算符接受一个或两个参数。这些参数是匹配时间戳之间距离的阈值。

  • 如果只给出一个参数,则它用于开始和结束时间戳。

  • 如果给出两个参数,则第一个用作开始时间戳的阈值,第二个用作结束时间戳的阈值。

换一种说法:

$eventA : EventA( this coincides[15s, 10s] $eventB )

以上模式将匹配当且仅当:

abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 15s &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 10s

对参数使用负间隔值是没有意义的,如果发生这种情况,Drools引擎会引发错误。

8.1.4 During (期间)

在评估事件发生期间当前事件发生时,评估者关联两个事件并匹配。

例如:

$eventA : EventA( this during $eventB )

相当于:
$eventB.startTimestamp < $eventA.startTimestamp <= $eventA.endTimestamp < $eventB.endTimestamp

during运算符接受1,2或4个可选参数,如下所示:

$eventA : EventA( this during[ 5s ] $eventB )
相当于:
0 < $eventA.startTimestamp - $eventB.startTimestamp <= 5s &&
0 < $eventB.endTimestamp - $eventA.endTimestamp <= 5s

$eventA : EventA( this during[ 5s, 10s ] $eventB )
相当于:
5s <= $eventA.startTimestamp - $eventB.startTimestamp <= 10s &&
5s <= $eventB.endTimestamp - $eventA.endTimestamp <= 10s
eventA : EventA( this during[ 2s, 6s, 4s, 10s ] $eventB )
相当于:
2s <= $eventA.startTimestamp - $eventB.startTimestamp <= 6s &&
4s <= $eventB.endTimestamp - $eventA.endTimestamp <= 10s

8.1.5 Includes

包含评估器在当前事件期间发生关联事件时关联两个事件和匹配。它是评估者During的对立面。

例如:

$eventA : EventA( this includes $eventB )
相当于:
$eventA.startTimestamp < $eventB.startTimestamp <= $eventB.endTimestamp < $eventA.endTimestamp

包含运算符接受1,2或4个可选参数,如下所示:

$eventA : EventA( this includes[ 5s ] $eventB )
相当于:
0 < $eventB.startTimestamp - $eventA.startTimestamp <= 5s &&
0 < $eventA.endTimestamp - $eventB.endTimestamp <= 5s
$eventA : EventA( this includes[ 5s, 10s ] $eventB )
相当于:
5s <= $eventB.startTimestamp - $eventA.startTimestamp <= 10s &&
5s <= $eventA.endTimestamp - $eventB.endTimestamp <= 10s
$eventA : EventA( this includes[ 2s, 6s, 4s, 10s ] $eventB )
相当于:
2s <= $eventB.startTimestamp - $eventA.startTimestamp <= 6s &&
4s <= $eventA.endTimestamp - $eventB.endTimestamp <= 10s

8.1.6 Finishes

当关联事件的开始时间戳发生在当前事件的开始时间戳之后,完成评估器关联两个事件并匹配,但两个结束时间戳同时发生。对参数使用负间隔值是没有意义的,如果发生这种情况,Drools引擎将引发异常。

例如:

$eventA : EventA( this finishes $eventB )
相当于:
$eventB.startTimestamp < $eventA.startTimestamp &&
$eventA.endTimestamp == $eventB.endTimestamp
$eventA : EventA( this finishes[ 5s ] $eventB )
相当于:
$eventB.startTimestamp < $eventA.startTimestamp &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s

8.1.7 Finished By

当当前事件开始时间戳发生在相关事件开始时间戳之前时,finishedby评估器关联两个事件并匹配,但两个结束时间戳同时发生。这是Finishes的对称对立面。

例如:

$eventA : EventA( this finishedby $eventB )
相当于:
$eventA.startTimestamp < $eventB.startTimestamp &&
$eventA.endTimestamp == $eventB.endTimestamp
$eventA : EventA( this finishedby[ 5s ] $eventB )
相当于:
$eventA.startTimestamp < $eventB.startTimestamp &&
abs( $eventA.endTimestamp - $eventB.endTimestamp ) <= 5s

8.1.8 Meets

当当前事件的结束时间戳与相关事件的开始时间戳同时发生时,满足评估器关联两个事件和匹配。

例如:

$eventA : EventA( this meets $eventB )
相当于:
abs( $eventB.startTimestamp - $eventA.endTimestamp ) == 0

meet评估器接受一个可选参数。如果已定义,则确定当前事件的结束时间戳与相关事件的开始时间戳之间的最大距离,以便操作员匹配。例:

$eventA : EventA( this meets[ 5s ] $eventB )
相当于:
abs( $eventB.startTimestamp - $eventA.endTimestamp) <= 5s

8.1.9 Met By

当当前事件的开始时间戳与相关事件的结束时间戳同时发生时,关联两个事件并匹配。

例如:

$eventA : EventA( this metby $eventB )
相当于:
abs( $eventA.startTimestamp - $eventB.endTimestamp ) == 0

metby评估器接受一个可选参数。如果已定义,则确定相关事件的结束时间戳与当前事件的开始时间戳之间的最大距离,以便操作员匹配。例:

$eventA : EventA( this metby[ 5s ] $eventB )
相当于:
abs( $eventA.startTimestamp - $eventB.endTimestamp) <= 5s

8.1.10  Overlaps

将当前事件在相关事件开始之前开始并且在相关事件开始之后但在相关事件结束之前结束时关联两个事件和匹配。换句话说,两个事件都有重叠的时期。

$eventA : EventA( this overlaps $eventB )
相当于:
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp

重叠运算符接受1或2个可选参数,如下所示:

$eventA : EventA( this overlaps[ 5s ] $eventB )
相当于:
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp &&
0 <= $eventA.endTimestamp - $eventB.startTimestamp <= 5s
$eventA : EventA( this overlaps[ 5s, 10s ] $eventB )
相当于:
$eventA.startTimestamp < $eventB.startTimestamp < $eventA.endTimestamp < $eventB.endTimestamp &&
5s <= $eventA.endTimestamp - $eventB.startTimestamp <= 10s

8.1.11 Overlapped By

当相关事件在当前事件开始之前开始并且在当前事件开始之后但在当前事件结束之前结束时,重叠的评估器关联两个事件和匹配。换句话说,两个事件都有重叠的时期。

$eventA : EventA( this overlappedby $eventB )
相当于:
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp

overlappedby运算符接受1或2个可选参数,如下所示:

$eventA : EventA( this overlappedby[ 5s ] $eventB )
相当于:
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp &&
0 <= $eventB.endTimestamp - $eventA.startTimestamp <= 5s
$eventA : EventA( this overlappedby[ 5s, 10s ] $eventB )
相当于:
$eventB.startTimestamp < $eventA.startTimestamp < $eventB.endTimestamp < $eventA.endTimestamp &&
5s <= $eventB.endTimestamp - $eventA.startTimestamp <= 10s

 8.1.12 Starts

当当前事件的结束时间戳发生在相关事件的结束时间戳之前时,启动评估器将两个事件和匹配相关联,但两个开始时间戳同时发生。

$eventA : EventA( this starts $eventB )
相当于:
$eventA.startTimestamp == $eventB.startTimestamp &&
$eventA.endTimestamp < $eventB.endTimestamp

启动计算器接受一个可选参数。如果已定义,则确定两个事件的开始时间戳之间的最大距离,以便操作员匹配。例:

$eventA : EventA( this starts[ 5s ] $eventB )
相当于:
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
$eventA.endTimestamp < $eventB.endTimestamp

8.1.13  Started By

当相关事件的结束时间戳发生在当前事件的结束时间戳之前,启动的评估器将两个事件和匹配相关联,但两个开始时间戳同时发生。让我们看一个例子:

$eventA : EventA( this startedby $eventB )
相当于:
$eventA.startTimestamp == $eventB.startTimestamp &&
$eventA.endTimestamp > $eventB.endTimestamp

startedby计算器接受一个可选参数。如果已定义,则确定两个事件的开始时间戳之间的最大距离,以便操作员匹配。例:

$eventA : EventA( this starts[ 5s ] $eventB )
相当于:
abs( $eventA.startTimestamp - $eventB.startTimestamp ) <= 5s &&
$eventA.endTimestamp > $eventB.endTimestamp

猜你喜欢

转载自blog.csdn.net/top_explore/article/details/93882257