流口水没有时间的规则

问题描述

我是Drools的新手。我需要使用spring-boot&Drools(7.40.0.Final)构建一个应用程序,其中springboot应用程序将流外部源,该外部源将连续触发数据包(跟踪与实体移动相关的数据)到我的应用程序。我需要评估所有这些流数据。

我正在使用“ geofence_rule.drl”文件来保存与地理位置相关的规则。

rule "Rule for Tag position in room 1"
when
    model : ComponentModel(positionValue <= 50)
then
    model.setRoomId(1);
end

rule "Rule for Tag position in room 2"
when
    model : ComponentModel(positionValue > 50)))
then
    model.setRoomId(2);
end

模型类如下。

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ComponentModel{

    private long tagId;
    private long roomId;
    private int positionValue;

}

我可能会获得与位置有关的数据,例如“ tag1”,“ tag2”,“ tag3”等“ n”个标签。我需要计算最近5分钟内房间1是否缺少标签1 (这意味着标签1的数据未达到“房间1中标签位置的规则”)。在Drools中是否支持这种计算?

我在drools文档中看到了“ not”关键字。但这只是否定了规则的条件。我需要检查最近几分钟规则是否符合要求,该时间限制可以在应用程序中配置。

解决方法

您正在寻找stream modenegative patterns。链接指向Drools官方文档。

流模式是Drools中的两个事件模式之一。默认为“云”模式,在此模式下,您可以预先掌握所有事实,并自动做出决策。另一种模式是“流”模式,用于处理时间流,这听起来很像您的“ ping”应用程序。在流模式下,Drools对每个事实进行评估,并知道时间-即其他事实何时进入。

流模式中的负模式是not关键字的逻辑时间扩展。正如您正确指出的那样,在云模式下,它只是消除条件(例如,“工作内存中没有条件符合此条件。”)。但是,在流模式下,您可以更新这些模式以在一段时间内生效时间。

Drools文档提供了以下示例:

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

“ when”子句中的第一行标识心跳($h)的实例。第二个标识在10秒内未收到心跳的情况。如果两个条件都成立,则执行规则-在这种情况下,将触发警报。

这与您应用于规则的模式相同。

rule "Tag has not been in Room 1 for 5 minutes"
when
  // Tag with ID 1,present in Room 1 -- First instance
  $tag: ComponentModel( tagId == 1,roomId == 1 ) from entry-point "TrackingStream"

  // Trigger if this condition hasn't been met a second time within 5 minutes
  not( ComponentModel( 
    this != $tag,tagId == 1,roomId == 1,5m] $tag ) from entry-point "TrackingStream")
then
  // Do whatever it is you need to do for this condition
end

在这种情况下,我利用了after时态运算符(链接到Drools文档。)

基本上就是这样-

$tag: ComponentModel( tagId == 1,roomId == 1 ) from entry-point "TrackingStream"

第一个条件标识场景,在这种情况下,ID 1位于房间1中。它标识了我们正在跟踪的场景的当前实例。由于这是时间流,因此很容易将其视为“已标记的实体(1)刚刚进入1号会议室”。

not( ComponentModel( 
  this != $tag,5m] $tag 
) from entry-point "TrackingStream")

这是魔术发生的地方,语法需要一些时间来习惯。第二个条件是等待 next 时间,然后检查条件。检查的条件是:

  • TagID为1,
  • RoomId为5

时间约束(this after[0s,5m] $tag)表示要等待检查此条件。如果在$tag之后的此时间段内收到第二个ComponentModel,则该规则将不会触发,并且场景将重复等待最多5分钟。由于时间范围[0s,5m]立即开始检查,因此我们需要从$tag子句(not(...)中的匹配项中显式排除this != $tag


为了说明,这是它的执行方式(简化):

  • 0m:00s-收到事件A〜(id = 1,房间= 1)。 $tag =事件A。我们开始检查输入流中是否存在第二种情况。
  • 0m:30s-收到事件B〜(id = 2,房间= 1)。 ID不匹配;忽略了。
  • 0m:45s-收到事件C〜(id = 1,房间= 1)。事件规则匹配“已取消”。现在检查$tag =事件C。
  • 5m:45s-5分钟内未收到匹配事件,事件C的规则触发右侧。

相关问答

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